<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<meta name="theme-color" content="#222" media="(prefers-color-scheme: light)">
<meta name="theme-color" content="#222" media="(prefers-color-scheme: dark)"><meta name="generator" content="Hexo 6.3.0">

  <link rel="apple-touch-icon" sizes="180x180" href="/hexo/images/apple-touch-icon-next.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/hexo/images/favicon-32x32-next.png">
  <link rel="icon" type="image/png" sizes="16x16" href="/hexo/images/favicon-16x16-next.png">
  <link rel="mask-icon" href="/hexo/images/logo.svg" color="#222">

<link rel="stylesheet" href="/hexo/css/main.css">



<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.1/css/all.min.css" integrity="sha256-Z1K5uhUaJXA7Ll0XrZ/0JhX4lAtZFpT6jkKrEDT0drU=" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.1.1/animate.min.css" integrity="sha256-PR7ttpcvz8qrF57fur/yAx1qXMFJeJFiA6pSzWi0OIE=" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/pace/1.2.4/themes/blue/pace-theme-bounce.css">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/pace/1.2.4/pace.min.js" integrity="sha256-gqd7YTjg/BtfqWSwsJOvndl0Bxc8gFImLEkXQT8+qj0=" crossorigin="anonymous"></script>

<script class="next-config" data-name="main" type="application/json">{"hostname":"codeleader.gitee.io","root":"/hexo/","images":"/hexo/images","scheme":"Gemini","darkmode":true,"version":"8.14.2","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12},"copycode":{"enable":true,"style":"mac"},"bookmark":{"enable":false,"color":"#222","save":"auto"},"mediumzoom":false,"lazyload":true,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"stickytabs":false,"motion":{"enable":true,"async":false,"transition":{"menu_item":"fadeInDown","post_block":"fadeIn","post_header":"fadeInDown","post_body":"fadeInDown","coll_header":"fadeInLeft","sidebar":"fadeInUp"}},"prism":false,"i18n":{"placeholder":"搜索...","empty":"没有找到任何搜索结果：${query}","hits_time":"找到 ${hits} 个搜索结果（用时 ${time} 毫秒）","hits":"找到 ${hits} 个搜索结果"},"path":"/hexo/search.xml","localsearch":{"enable":true,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false}}</script><script src="/hexo/js/config.js"></script>

    <meta name="description" content="快手一面 1、重载和重写的区别？调用的时候怎么确定调用的是哪个？  方法重载：发生在同一个类中，拥有两个或更多个名称相同但参数列表(参数类型、参数个数)不同的方法，方法的重载与返回值类型无关。 方法重写：发生在当子类继承父类时，对父类中的一些方法根据自己需求进行重写操作。  方法的重写发生在运行时，因为在编译时，编译器无法知道我们到底是调用的父类方法还是子类方法，只有在实际运行的时候才">
<meta property="og:type" content="article">
<meta property="og:title" content="快手一面">
<meta property="og:url" content="https://codeleader.gitee.io/hexo/2023/08/11/%E5%BF%AB%E6%89%8B%E4%B8%80%E9%9D%A2/index.html">
<meta property="og:site_name" content="CodeLeader">
<meta property="og:description" content="快手一面 1、重载和重写的区别？调用的时候怎么确定调用的是哪个？  方法重载：发生在同一个类中，拥有两个或更多个名称相同但参数列表(参数类型、参数个数)不同的方法，方法的重载与返回值类型无关。 方法重写：发生在当子类继承父类时，对父类中的一些方法根据自己需求进行重写操作。  方法的重写发生在运行时，因为在编译时，编译器无法知道我们到底是调用的父类方法还是子类方法，只有在实际运行的时候才">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://codeleader.oss-cn-beijing.aliyuncs.com/site/image-20230807215419666.png">
<meta property="og:image" content="https://codeleader.oss-cn-beijing.aliyuncs.com/site/image-20230708164303190.png">
<meta property="og:image" content="https://codeleader.oss-cn-beijing.aliyuncs.com/site/image-20230708164340649.png">
<meta property="og:image" content="https://codeleader.oss-cn-beijing.aliyuncs.com/site/image-20230808111612153.png">
<meta property="og:image" content="https://codeleader.oss-cn-beijing.aliyuncs.com/site/image-20230708174345789.png">
<meta property="og:image" content="https://codeleader.oss-cn-beijing.aliyuncs.com/site/image-20230708174317589.png">
<meta property="og:image" content="https://codeleader.oss-cn-beijing.aliyuncs.com/site/image-20230801155155628.png">
<meta property="og:image" content="https://codeleader.oss-cn-beijing.aliyuncs.com/site/image-20230801155454797.png">
<meta property="og:image" content="https://codeleader.oss-cn-beijing.aliyuncs.com/site/image-20230801155747152.png">
<meta property="og:image" content="https://codeleader.oss-cn-beijing.aliyuncs.com/site/image-20230801155910501.png">
<meta property="og:image" content="https://codeleader.oss-cn-beijing.aliyuncs.com/site/image-20230801163556062.png">
<meta property="og:image" content="https://codeleader.oss-cn-beijing.aliyuncs.com/site/230ae587a322d6e4d09510161987d346.jpeg">
<meta property="og:image" content="https://codeleader.oss-cn-beijing.aliyuncs.com/site/image-20230808164719217.png">
<meta property="og:image" content="https://codeleader.oss-cn-beijing.aliyuncs.com/site/image-20230808152038722.png">
<meta property="og:image" content="https://codeleader.oss-cn-beijing.aliyuncs.com/site/image-20230808153322054.png">
<meta property="og:image" content="https://codeleader.oss-cn-beijing.aliyuncs.com/site/image-20230803171654565.png">
<meta property="og:image" content="https://codeleader.oss-cn-beijing.aliyuncs.com/site/image-20230803172257557.png">
<meta property="og:image" content="https://codeleader.oss-cn-beijing.aliyuncs.com/site/image-20230810165036137.png">
<meta property="og:image" content="https://codeleader.oss-cn-beijing.aliyuncs.com/site/image-20230811113606308.png">
<meta property="og:image" content="https://codeleader.oss-cn-beijing.aliyuncs.com/site/image-20230811135708995.png">
<meta property="og:image" content="https://codeleader.oss-cn-beijing.aliyuncs.com/site/image-20230811100217214.png">
<meta property="article:published_time" content="2023-08-11T06:18:43.760Z">
<meta property="article:modified_time" content="2023-08-11T08:22:20.564Z">
<meta property="article:author" content="别团等shy哥发育">
<meta property="article:tag" content="Java">
<meta property="article:tag" content="面经">
<meta property="article:tag" content="MySQL">
<meta property="article:tag" content="Redis">
<meta property="article:tag" content="RabbitMQ">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://codeleader.oss-cn-beijing.aliyuncs.com/site/image-20230807215419666.png">


<link rel="canonical" href="https://codeleader.gitee.io/hexo/2023/08/11/%E5%BF%AB%E6%89%8B%E4%B8%80%E9%9D%A2/">



<script class="next-config" data-name="page" type="application/json">{"sidebar":"","isHome":false,"isPost":true,"lang":"zh-CN","comments":true,"permalink":"https://codeleader.gitee.io/hexo/2023/08/11/%E5%BF%AB%E6%89%8B%E4%B8%80%E9%9D%A2/","path":"2023/08/11/快手一面/","title":"快手一面"}</script>

<script class="next-config" data-name="calendar" type="application/json">""</script>
<title>快手一面 | CodeLeader</title>
  








  <noscript>
    <link rel="stylesheet" href="/hexo/css/noscript.css">
  </noscript>
<style>mjx-container[jax="SVG"] {
  direction: ltr;
}

mjx-container[jax="SVG"] > svg {
  overflow: visible;
}

mjx-container[jax="SVG"][display="true"] {
  display: block;
  text-align: center;
  margin: 1em 0;
}

mjx-container[jax="SVG"][justify="left"] {
  text-align: left;
}

mjx-container[jax="SVG"][justify="right"] {
  text-align: right;
}

g[data-mml-node="merror"] > g {
  fill: red;
  stroke: red;
}

g[data-mml-node="merror"] > rect[data-background] {
  fill: yellow;
  stroke: none;
}

g[data-mml-node="mtable"] > line[data-line] {
  stroke-width: 70px;
  fill: none;
}

g[data-mml-node="mtable"] > rect[data-frame] {
  stroke-width: 70px;
  fill: none;
}

g[data-mml-node="mtable"] > .mjx-dashed {
  stroke-dasharray: 140;
}

g[data-mml-node="mtable"] > .mjx-dotted {
  stroke-linecap: round;
  stroke-dasharray: 0,140;
}

g[data-mml-node="mtable"] > svg {
  overflow: visible;
}

[jax="SVG"] mjx-tool {
  display: inline-block;
  position: relative;
  width: 0;
  height: 0;
}

[jax="SVG"] mjx-tool > mjx-tip {
  position: absolute;
  top: 0;
  left: 0;
}

mjx-tool > mjx-tip {
  display: inline-block;
  padding: .2em;
  border: 1px solid #888;
  font-size: 70%;
  background-color: #F8F8F8;
  color: black;
  box-shadow: 2px 2px 5px #AAAAAA;
}

g[data-mml-node="maction"][data-toggle] {
  cursor: pointer;
}

mjx-status {
  display: block;
  position: fixed;
  left: 1em;
  bottom: 1em;
  min-width: 25%;
  padding: .2em .4em;
  border: 1px solid #888;
  font-size: 90%;
  background-color: #F8F8F8;
  color: black;
}

foreignObject[data-mjx-xml] {
  font-family: initial;
  line-height: normal;
  overflow: visible;
}

.MathJax path {
  stroke-width: 3;
}

mjx-container[display="true"] {
  overflow: auto hidden;
}

mjx-container[display="true"] + br {
  display: none;
}
</style></head>

<body itemscope itemtype="http://schema.org/WebPage" class="use-motion">
  <div class="headband"></div>

  <main class="main">
    <div class="column">
      <header class="header" itemscope itemtype="http://schema.org/WPHeader"><div class="site-brand-container">
  <div class="site-nav-toggle">
    <div class="toggle" aria-label="切换导航栏" role="button">
        <span class="toggle-line"></span>
        <span class="toggle-line"></span>
        <span class="toggle-line"></span>
    </div>
  </div>

  <div class="site-meta">

    <a href="/hexo/" class="brand" rel="start">
      <i class="logo-line"></i>
      <p class="site-title">CodeLeader</p>
      <i class="logo-line"></i>
    </a>
      <p class="site-subtitle" itemprop="description">欲买桂花同载酒，终不似少年游</p>
  </div>

  <div class="site-nav-right">
    <div class="toggle popup-trigger" aria-label="搜索" role="button">
        <i class="fa fa-search fa-fw fa-lg"></i>
    </div>
  </div>
</div>



<nav class="site-nav">
  <ul class="main-menu menu"><li class="menu-item menu-item-home"><a href="/hexo/" rel="section"><i class="fa fa-home fa-fw"></i>首页</a></li><li class="menu-item menu-item-about"><a href="/hexo/about/" rel="section"><i class="fa fa-user fa-fw"></i>关于</a></li><li class="menu-item menu-item-tags"><a href="/hexo/tags/" rel="section"><i class="fa fa-tags fa-fw"></i>标签<span class="badge">19</span></a></li><li class="menu-item menu-item-categories"><a href="/hexo/categories/" rel="section"><i class="fa fa-th fa-fw"></i>分类<span class="badge">4</span></a></li><li class="menu-item menu-item-archives"><a href="/hexo/archives/" rel="section"><i class="fa fa-archive fa-fw"></i>归档<span class="badge">17</span></a></li><li class="menu-item menu-item-schedule"><a href="/hexo/schedule/" rel="section"><i class="fa fa-calendar fa-fw"></i>日程表</a></li><li class="menu-item menu-item-sitemap"><a href="/hexo/sitemap.xml" rel="section"><i class="fa fa-sitemap fa-fw"></i>站点地图</a></li><li class="menu-item menu-item-commonweal"><a href="/hexo/404/" rel="section"><i class="fa fa-heartbeat fa-fw"></i>公益 404</a></li>
      <li class="menu-item menu-item-search">
        <a role="button" class="popup-trigger"><i class="fa fa-search fa-fw"></i>搜索
        </a>
      </li>
  </ul>
</nav>



  <div class="search-pop-overlay">
    <div class="popup search-popup"><div class="search-header">
  <span class="search-icon">
    <i class="fa fa-search"></i>
  </span>
  <div class="search-input-container">
    <input autocomplete="off" autocapitalize="off" maxlength="80"
           placeholder="搜索..." spellcheck="false"
           type="search" class="search-input">
  </div>
  <span class="popup-btn-close" role="button">
    <i class="fa fa-times-circle"></i>
  </span>
</div>
<div class="search-result-container no-result">
  <div class="search-result-icon">
    <i class="fa fa-spinner fa-pulse fa-5x"></i>
  </div>
</div>

    </div>
  </div>

</header>
        
  
  <aside class="sidebar">

    <div class="sidebar-inner sidebar-nav-active sidebar-toc-active">
      <ul class="sidebar-nav">
        <li class="sidebar-nav-toc">
          文章目录
        </li>
        <li class="sidebar-nav-overview">
          站点概览
        </li>
      </ul>

      <div class="sidebar-panel-container">
        <!--noindex-->
        <div class="post-toc-wrap sidebar-panel">
            <div class="post-toc animated"><ol class="nav"><li class="nav-item nav-level-1"><a class="nav-link" href="#%E5%BF%AB%E6%89%8B%E4%B8%80%E9%9D%A2"><span class="nav-number">1.</span> <span class="nav-text">快手一面</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#%E9%87%8D%E8%BD%BD%E5%92%8C%E9%87%8D%E5%86%99%E7%9A%84%E5%8C%BA%E5%88%AB%E8%B0%83%E7%94%A8%E7%9A%84%E6%97%B6%E5%80%99%E6%80%8E%E4%B9%88%E7%A1%AE%E5%AE%9A%E8%B0%83%E7%94%A8%E7%9A%84%E6%98%AF%E5%93%AA%E4%B8%AA"><span class="nav-number">1.0.1.</span> <span class="nav-text">1、重载和重写的区别？调用的时候怎么确定调用的是哪个？</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#java%E6%94%AF%E6%8C%81%E5%A4%9A%E7%BB%A7%E6%89%BF%E5%90%97"><span class="nav-number">1.0.2.</span> <span class="nav-text">2、Java支持多继承吗？</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#string%E7%B1%BB%E4%BA%86%E8%A7%A3%E5%90%97%E4%B8%8D%E5%8F%AF%E5%8F%98%E6%80%A7%E8%A1%A8%E7%8E%B0%E5%9C%A8%E5%93%AA%E6%88%91%E5%A6%82%E6%9E%9C%E5%88%9B%E5%BB%BAstring%E5%AF%B9%E8%B1%A1%E7%9A%84%E8%AF%9D%E6%94%B9%E4%BA%86%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%9A%84%E5%80%BC%E9%82%A3%E6%94%B9%E5%8F%98%E5%B1%9E%E6%80%A7%E7%9A%84%E8%AF%9D%E6%98%AF%E4%B8%8D%E6%98%AF%E5%B0%B1%E5%8F%98%E4%BA%86"><span class="nav-number">1.0.3.</span> <span class="nav-text">3、String类了解吗？不可变性表现在哪？我如果创建String对象的话，改了字符串的值，那改变属性的话是不是就变了？</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#string%E8%AE%BE%E8%AE%A1%E4%B8%BA%E4%B8%8D%E5%8F%AF%E5%8F%98%E7%9A%84%E5%A5%BD%E5%A4%84%E6%9C%89%E5%93%AA%E4%BA%9B"><span class="nav-number">1.0.4.</span> <span class="nav-text">4、String设计为不可变的好处有哪些？</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#java%E5%BC%82%E5%B8%B8%E4%BD%93%E7%B3%BB%E4%BA%86%E8%A7%A3%E5%90%97error%E8%83%BD%E8%A2%AB%E6%8D%95%E8%8E%B7%E5%90%97catch%E8%83%BDcarch-error%E5%90%97"><span class="nav-number">1.0.5.</span> <span class="nav-text">Java异常体系了解吗？Error能被捕获吗？Catch能carch Error吗?</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E5%A4%9A%E4%B8%AA%E7%BA%BF%E7%A8%8B%E8%BF%90%E8%A1%8C%E5%88%B0error%E7%9A%84%E6%97%B6%E5%80%99%E5%8F%AA%E6%98%AF%E5%81%9C%E4%B8%80%E4%B8%AA%E7%BA%BF%E7%A8%8B%E8%BF%98%E6%98%AF%E8%BF%99%E4%B8%AA%E8%BF%9B%E7%A8%8B%E5%B0%B1%E5%81%9C%E4%BA%86"><span class="nav-number">1.0.6.</span> <span class="nav-text">多个线程运行到Error的时候，只是停一个线程还是这个进程就停了？</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E8%AF%B4%E8%AF%B4%E5%B8%B8%E8%A7%81%E7%9A%84runtimeexception%E9%9D%9E%E5%8F%97%E6%A3%80%E5%BC%82%E5%B8%B8"><span class="nav-number">1.0.7.</span> <span class="nav-text">说说常见的RuntimeException(非受检异常)</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E6%9C%89%E5%A4%84%E7%90%86%E8%BF%87%E7%BC%96%E8%AF%91%E6%97%B6%E5%BC%82%E5%B8%B8%E5%90%97"><span class="nav-number">1.0.8.</span> <span class="nav-text">有处理过编译时异常吗？</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#io%E6%93%8D%E4%BD%9C%E7%9A%84%E5%BC%82%E5%B8%B8%E6%98%AF%E4%B8%8D%E6%98%AF%E5%BF%85%E9%A1%BB%E8%A6%81%E6%8D%95%E8%8E%B7"><span class="nav-number">1.0.9.</span> <span class="nav-text">I&#x2F;O操作的异常是不是必须要捕获？</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#java%E7%9A%84%E5%8F%8D%E5%B0%84%E4%BA%86%E8%A7%A3%E5%90%97"><span class="nav-number">1.0.10.</span> <span class="nav-text">Java的反射了解吗？</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E7%94%A8%E5%8F%8D%E5%B0%84%E7%9A%84%E6%97%B6%E5%80%99%E5%A6%82%E6%9E%9C%E4%B8%80%E4%B8%AA%E7%B1%BB%E6%98%AF%E7%A7%81%E6%9C%89%E7%9A%84%E6%9C%89%E4%B8%80%E4%B8%AA%E7%A7%81%E6%9C%89%E7%9A%84%E5%B1%9E%E6%80%A7%E8%83%BD%E7%94%A8%E5%8F%8D%E5%B0%84%E4%BF%AE%E6%94%B9%E8%BF%99%E4%B8%AA%E5%80%BC%E5%90%97"><span class="nav-number">1.0.11.</span> <span class="nav-text">用反射的时候，如果一个类是私有的，有一个私有的属性，能用反射修改这个值吗？</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E7%94%A8%E8%BF%87hashmap%E7%9C%8B%E8%BF%87%E5%BA%95%E5%B1%82%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E5%90%97"><span class="nav-number">1.0.12.</span> <span class="nav-text">用过HashMap？看过底层数据结构吗？</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#hashmap%E6%98%AF%E7%BA%BF%E7%A8%8B%E5%AE%89%E5%85%A8%E7%9A%84%E5%90%97%E5%93%AA%E4%BA%9B%E5%9C%B0%E6%96%B9%E4%BC%9A%E5%8F%91%E7%94%9F%E7%BA%BF%E7%A8%8B%E4%B8%8D%E5%AE%89%E5%85%A8%E5%BE%85%E8%A1%A5%E5%85%85"><span class="nav-number">1.0.13.</span> <span class="nav-text">HashMap是线程安全的吗？哪些地方会发生线程不安全(待补充)？</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#threadlocal%E7%94%A8%E8%BF%87%E5%90%97%E5%AE%83%E6%98%AF%E6%80%8E%E4%B9%88%E8%A7%A3%E5%86%B3%E7%BA%BF%E7%A8%8B%E5%AE%89%E5%85%A8%E7%9A%84%E7%BB%93%E6%9E%84%E4%BA%86%E8%A7%A3%E5%90%97"><span class="nav-number">1.0.14.</span> <span class="nav-text">ThreadLocal用过吗？它是怎么解决线程安全的？结构了解吗？</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#concurrenthashmap%E6%98%AF%E9%80%9A%E8%BF%87%E4%BB%80%E4%B9%88%E6%96%B9%E5%BC%8F%E5%AE%9E%E7%8E%B0%E7%9A%84%E7%BA%BF%E7%A8%8B%E5%AE%89%E5%85%A8"><span class="nav-number">1.0.15.</span> <span class="nav-text">ConcurrentHashMap是通过什么方式实现的线程安全？</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E7%BA%BF%E7%A8%8B%E6%B1%A0%E7%94%A8%E8%BF%87%E5%90%97%E5%88%9B%E5%BB%BA%E7%BA%BF%E7%A8%8B%E7%9A%84%E5%B8%B8%E7%94%A8%E5%8F%82%E6%95%B0%E6%9C%89%E5%93%AA%E4%BA%9B%E6%8B%92%E7%BB%9D%E7%AD%96%E7%95%A5"><span class="nav-number">1.0.16.</span> <span class="nav-text">线程池用过吗？创建线程的常用参数？有哪些拒绝策略？</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E7%BA%BF%E7%A8%8B%E9%80%9A%E4%BF%A1%E6%96%B9%E5%BC%8F%E5%BE%85%E8%A1%A5%E5%85%85"><span class="nav-number">1.0.17.</span> <span class="nav-text">线程通信方式(待补充)</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E7%9C%8B%E4%BD%A0%E6%9C%89%E5%AE%9E%E4%B9%A0%E7%BB%8F%E5%8E%86%E5%92%8C%E9%A1%B9%E7%9B%AE%E7%BB%8F%E5%8E%86%E4%B9%8B%E5%89%8D%E5%A4%84%E7%90%86%E7%BA%BF%E7%A8%8B%E6%B1%A0%E7%9A%84%E6%8B%92%E7%BB%9D%E7%AD%96%E7%95%A5%E7%94%A8%E4%BB%80%E4%B9%88%E6%8E%AA%E6%96%BD%E5%A4%84%E7%90%86%E7%9A%84%E9%82%A3%E4%BB%BB%E5%8A%A1%E6%95%B0%E5%A4%9A%E4%BA%86%E7%9A%84%E8%AF%9D%E8%83%BD%E7%9F%A5%E9%81%93%E5%93%AA%E4%B8%AA%E4%B8%9A%E5%8A%A1%E8%A7%A6%E5%8F%91%E7%9A%84%E5%90%97"><span class="nav-number">1.0.18.</span> <span class="nav-text">看你有实习经历和项目经历，之前处理线程池的拒绝策略用什么措施处理的？那任务数多了的话能知道哪个业务触发的吗？</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E4%BD%A0%E5%AF%B9synchronized%E5%85%B3%E9%94%AE%E5%AD%97%E7%9A%84%E7%90%86%E8%A7%A3"><span class="nav-number">1.0.19.</span> <span class="nav-text">你对Synchronized关键字的理解</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E4%BA%86%E8%A7%A3%E9%94%81%E7%9A%84%E4%BC%98%E5%8C%96%E5%90%97jdk1.6%E4%B9%8B%E5%90%8E%E5%AF%B9%E9%94%81%E8%BF%9B%E8%A1%8C%E4%BA%86%E5%A4%A7%E9%87%8F%E7%9A%84%E4%BC%98%E5%8C%96%E4%BD%A0%E4%BA%86%E8%A7%A3%E5%90%97"><span class="nav-number">1.0.20.</span> <span class="nav-text">了解锁的优化吗？JDK1.6之后对锁进行了大量的优化，你了解吗？</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#reentrantlock%E4%BA%86%E8%A7%A3%E5%90%97%E5%92%8Csynchronized%E6%9C%89%E4%BB%80%E4%B9%88%E5%8C%BA%E5%88%AB%E6%98%AF%E5%85%AC%E5%B9%B3%E9%94%81%E5%90%97"><span class="nav-number">1.0.21.</span> <span class="nav-text">ReentrantLock了解吗？和synchronized有什么区别？是公平锁吗？</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E5%8D%95%E4%BE%8B%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%BA%86%E8%A7%A3%E5%90%97%E6%80%8E%E4%B9%88%E5%AE%9E%E7%8E%B0%E7%9A%84"><span class="nav-number">1.0.22.</span> <span class="nav-text">单例设计模式了解吗？怎么实现的？</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#mysql%E5%B8%B8%E7%94%A8%E7%9A%84%E7%B4%A2%E5%BC%95%E7%BB%93%E6%9E%84%E6%9C%89%E5%93%AA%E4%BA%9B"><span class="nav-number">1.0.23.</span> <span class="nav-text">MySQL常用的索引结构有哪些？</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#b%E6%A0%91%E7%9A%84%E6%AF%8F%E4%B8%AA%E7%B4%A2%E5%BC%95%E9%83%BD%E4%BC%9A%E5%AD%98%E5%82%A8%E6%AF%8F%E4%B8%80%E8%A1%8C%E7%9A%84%E8%AE%B0%E5%BD%95%E5%90%97"><span class="nav-number">1.0.24.</span> <span class="nav-text">B+树的每个索引都会存储每一行的记录吗？</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E5%B9%B6%E5%8F%91%E4%BA%8B%E5%8A%A1%E5%B8%A6%E6%9D%A5%E4%BA%86%E5%93%AA%E4%BA%9B%E9%97%AE%E9%A2%98"><span class="nav-number">1.0.25.</span> <span class="nav-text">并发事务带来了哪些问题？</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#mysql%E7%9A%84%E4%BA%8B%E5%8A%A1%E9%9A%94%E7%A6%BB%E7%BA%A7%E5%88%AB%E6%9C%89%E5%93%AA%E4%BA%9B%E6%AF%8F%E7%A7%8D%E9%9A%94%E7%A6%BB%E7%BA%A7%E5%88%AB%E5%8F%AF%E8%83%BD%E4%BC%9A%E4%BA%A7%E7%94%9F%E5%93%AA%E4%BA%9B%E9%97%AE%E9%A2%98"><span class="nav-number">1.0.26.</span> <span class="nav-text">MySQL的事务隔离级别有哪些？每种隔离级别可能会产生哪些问题？</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#aop%E6%80%9D%E6%83%B3%E6%98%AF%E4%BB%80%E4%B9%88%E5%8E%9F%E7%90%86%E4%BA%86%E8%A7%A3%E5%90%97%E5%BA%95%E5%B1%82%E6%98%AF%E6%80%8E%E4%B9%88%E5%AE%9E%E7%8E%B0%E7%9A%84"><span class="nav-number">1.0.27.</span> <span class="nav-text">AOP思想是什么？原理了解吗？底层是怎么实现的？</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#jdk%E5%8A%A8%E6%80%81%E4%BB%A3%E7%90%86%E4%BA%86%E8%A7%A3%E5%90%97"><span class="nav-number">1.0.28.</span> <span class="nav-text">JDK动态代理了解吗？</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#redis%E7%9A%84%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E6%9C%89%E5%93%AA%E4%BA%9B"><span class="nav-number">1.0.29.</span> <span class="nav-text">Redis的数据结构有哪些？</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#zset%E7%9A%84%E5%BA%95%E5%B1%82%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E6%98%AF%E4%BB%80%E4%B9%88%E8%B7%B3%E8%A1%A8%E4%BA%86%E8%A7%A3%E5%90%97"><span class="nav-number">1.0.30.</span> <span class="nav-text">ZSet的底层数据结构是什么？跳表了解吗？</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#redis%E7%9A%84%E6%8C%81%E4%B9%85%E5%8C%96%E7%AD%96%E7%95%A5"><span class="nav-number">1.0.31.</span> <span class="nav-text">Redis的持久化策略</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E9%94%AE%E7%9A%84%E8%BF%87%E6%9C%9F%E5%88%A0%E9%99%A4%E7%AD%96%E7%95%A5"><span class="nav-number">1.0.32.</span> <span class="nav-text">键的过期删除策略</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#redis%E5%AE%9E%E7%8E%B0%E5%88%86%E5%B8%83%E5%BC%8F%E9%94%81"><span class="nav-number">1.0.33.</span> <span class="nav-text">Redis实现分布式锁</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E9%A1%B9%E7%9B%AE%E4%B8%AD%E6%9C%89%E7%94%A8%E8%BF%87redis%E5%90%97"><span class="nav-number">1.0.34.</span> <span class="nav-text">项目中有用过Redis吗？</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E6%B6%88%E6%81%AF%E9%98%9F%E5%88%97%E7%94%A8%E8%BF%87%E5%90%97%E4%BD%A0%E8%A7%89%E5%BE%97%E4%B8%BA%E4%BB%80%E4%B9%88%E8%A6%81%E5%BC%95%E5%85%A5%E6%B6%88%E6%81%AF%E9%98%9F%E5%88%97%E5%91%A2%E4%B8%BE%E5%87%A0%E4%B8%AA%E5%BA%94%E7%94%A8%E5%9C%BA%E6%99%AF"><span class="nav-number">1.0.35.</span> <span class="nav-text">消息队列用过吗？你觉得为什么要引入消息队列呢？举几个应用场景</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E6%9D%A5%E4%B8%80%E9%81%93%E7%AE%97%E6%B3%95%E9%A2%98%E5%90%A7%E6%98%AF%E4%B8%AA%E6%B0%94%E6%B8%A9%E7%9A%84%E9%A2%98%E7%9B%AE%E5%8D%95%E8%B0%83%E6%A0%88"><span class="nav-number">1.0.36.</span> <span class="nav-text">来一道算法题吧？(是个气温的题目，单调栈)</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#jvm%E5%86%85%E5%AD%98%E6%A8%A1%E5%9E%8B%E7%B1%BB%E5%8A%A0%E8%BD%BD%E6%9C%BA%E5%88%B6%E5%8F%8C%E4%BA%B2%E5%A7%94%E6%B4%BE%E6%A8%A1%E5%9E%8B%E5%9E%83%E5%9C%BE%E5%9B%9E%E6%94%B6%E7%AE%97%E6%B3%95%E6%96%B0%E7%94%9F%E4%BB%A3%E5%9B%9E%E6%94%B6%E7%AD%96%E7%95%A5"><span class="nav-number">1.0.37.</span> <span class="nav-text">JVM内存模型、类加载机制、双亲委派模型、垃圾回收算法、新生代回收策略</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E4%BD%A0%E4%BA%86%E8%A7%A3%E5%93%AA%E4%BA%9B%E9%94%81"><span class="nav-number">1.0.38.</span> <span class="nav-text">你了解哪些锁？</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#java%E5%B9%B6%E5%8F%91%E5%85%B3%E9%94%AE%E5%AD%97"><span class="nav-number">1.0.39.</span> <span class="nav-text">Java并发关键字</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#volatile"><span class="nav-number">1.0.39.1.</span> <span class="nav-text">volatile</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#countdownlatch%E5%80%92%E8%AE%A1%E6%97%B6%E5%99%A8"><span class="nav-number">1.0.39.2.</span> <span class="nav-text">CountDownLatch(倒计时器)</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#cyclicbarrier%E5%BE%AA%E7%8E%AF%E6%A0%85%E6%A0%8F"><span class="nav-number">1.0.39.3.</span> <span class="nav-text">CyclicBarrier(循环栅栏)</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#semaphore%E4%BF%A1%E5%8F%B7%E9%87%8F"><span class="nav-number">1.0.39.4.</span> <span class="nav-text">Semaphore(信号量)</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#countdownlatch%E5%92%8Ccyclicbarrier%E7%9A%84%E5%8C%BA%E5%88%AB"><span class="nav-number">1.0.40.</span> <span class="nav-text">CountDownLatch和CyclicBarrier的区别</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#cas%E5%8E%9F%E7%90%86"><span class="nav-number">1.0.41.</span> <span class="nav-text">CAS原理</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#aba%E9%97%AE%E9%A2%98%E6%80%8E%E4%B9%88%E8%A7%A3%E5%86%B3"><span class="nav-number">1.0.42.</span> <span class="nav-text">ABA问题？怎么解决？</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#aqs"><span class="nav-number">1.0.43.</span> <span class="nav-text">AQS</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#aqs%E7%9A%84%E5%8E%9F%E7%90%86"><span class="nav-number">1.0.43.1.</span> <span class="nav-text">AQS的原理</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#aqs%E5%85%B1%E4%BA%AB%E8%B5%84%E6%BA%90%E7%9A%84%E6%96%B9%E5%BC%8F%E7%8B%AC%E5%8D%A0%E5%BC%8F%E5%92%8C%E5%85%B1%E4%BA%AB%E5%BC%8F"><span class="nav-number">1.0.43.2.</span> <span class="nav-text">AQS共享资源的方式：独占式和共享式</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#ioc%E7%9A%84%E7%90%86%E8%A7%A3"><span class="nav-number">1.0.44.</span> <span class="nav-text">IOC的理解</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E9%A1%B9%E7%9B%AE%E4%B8%BB%E8%A6%81%E8%B4%9F%E8%B4%A3%E5%93%AA%E4%BA%9B%E5%B7%A5%E4%BD%9C"><span class="nav-number">1.0.45.</span> <span class="nav-text">项目主要负责哪些工作？</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E6%95%B0%E6%8D%AE%E9%87%8F%E5%A4%A7%E6%80%8E%E4%B9%88%E5%8A%9E%E5%88%86%E5%BA%93%E5%88%86%E8%A1%A8%E5%85%B7%E4%BD%93%E6%80%8E%E4%B9%88%E8%AE%BE%E8%AE%A1"><span class="nav-number">1.0.46.</span> <span class="nav-text">数据量大怎么办，分库分表具体怎么设计？</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E9%A1%B9%E7%9B%AE%E4%B8%AD%E5%A4%9A%E7%BA%BF%E7%A8%8B%E6%80%8E%E4%B9%88%E7%94%A8%E7%9A%84"><span class="nav-number">1.0.47.</span> <span class="nav-text">项目中多线程怎么用的？</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E7%86%94%E6%96%AD%E9%99%8D%E7%BA%A7%E4%B8%8A%E4%B8%8B%E6%B8%B8%E6%80%8E%E4%B9%88%E5%A4%84%E7%90%86"><span class="nav-number">1.0.48.</span> <span class="nav-text">熔断降级上下游怎么处理？</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E9%99%A4%E4%BA%86%E5%B0%86%E6%97%A5%E5%BF%97%E4%BF%9D%E5%AD%98%E5%88%B0%E6%95%B0%E6%8D%AE%E5%BA%93%E8%BF%98%E5%8F%AF%E4%BB%A5%E6%80%8E%E4%B9%88%E5%A4%84%E7%90%86"><span class="nav-number">1.0.49.</span> <span class="nav-text">除了将日志保存到数据库还可以怎么处理？</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E7%BC%96%E7%A8%8B%E5%8A%9B%E6%89%A3151%E5%8F%8D%E8%BD%AC%E5%AD%97%E7%AC%A6%E4%B8%B2%E4%B8%AD%E7%9A%84%E5%8D%95%E8%AF%8D"><span class="nav-number">1.0.50.</span> <span class="nav-text">编程：力扣151反转字符串中的单词</span></a></li></ol></li></ol></li></ol></div>
        </div>
        <!--/noindex-->

        <div class="site-overview-wrap sidebar-panel">
          <div class="site-author animated" itemprop="author" itemscope itemtype="http://schema.org/Person">
    <img class="site-author-image" itemprop="image" alt="别团等shy哥发育"
      src="https://codeleader.oss-cn-beijing.aliyuncs.com/site/avatar.jpg">
  <p class="site-author-name" itemprop="name">别团等shy哥发育</p>
  <div class="site-description" itemprop="description">别团等shy哥发育的博客</div>
</div>
<div class="site-state-wrap animated">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
        <a href="/hexo/archives/">
          <span class="site-state-item-count">17</span>
          <span class="site-state-item-name">日志</span>
        </a>
      </div>
      <div class="site-state-item site-state-categories">
          <a href="/hexo/categories/">
        <span class="site-state-item-count">4</span>
        <span class="site-state-item-name">分类</span></a>
      </div>
      <div class="site-state-item site-state-tags">
          <a href="/hexo/tags/">
        <span class="site-state-item-count">19</span>
        <span class="site-state-item-name">标签</span></a>
      </div>
  </nav>
</div>
  <div class="links-of-author animated">
      <span class="links-of-author-item">
        <a href="https://github.com/xiongtete0519" title="GitHub → https:&#x2F;&#x2F;github.com&#x2F;xiongtete0519" rel="noopener me" target="_blank"><i class="fab fa-github fa-fw"></i>GitHub</a>
      </span>
      <span class="links-of-author-item">
        <a href="/hexo/xiongtete0519@gmail.com" title="E-Mail → xiongtete0519@gmail.com" rel="noopener me"><i class="fa fa-envelope fa-fw"></i>E-Mail</a>
      </span>
      <span class="links-of-author-item">
        <a href="https://codeleader.blog.csdn.net/" title="CSDN → https:&#x2F;&#x2F;codeleader.blog.csdn.net&#x2F;" rel="noopener me" target="_blank"><i class="fa CSDN fa-fw"></i>CSDN</a>
      </span>
  </div>

        </div>
      </div>
        <div class="back-to-top animated" role="button" aria-label="返回顶部">
          <i class="fa fa-arrow-up"></i>
          <span>0%</span>
        </div>
    </div>

    
  </aside>


    </div>

    <div class="main-inner post posts-expand">


  


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="https://codeleader.gitee.io/hexo/2023/08/11/%E5%BF%AB%E6%89%8B%E4%B8%80%E9%9D%A2/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="https://codeleader.oss-cn-beijing.aliyuncs.com/site/avatar.jpg">
      <meta itemprop="name" content="别团等shy哥发育">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="CodeLeader">
      <meta itemprop="description" content="别团等shy哥发育的博客">
    </span>

    <span hidden itemprop="post" itemscope itemtype="http://schema.org/CreativeWork">
      <meta itemprop="name" content="快手一面 | CodeLeader">
      <meta itemprop="description" content="">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          快手一面
        </h1>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>
      

      <time title="创建时间：2023-08-11 14:18:43 / 修改时间：16:22:20" itemprop="dateCreated datePublished" datetime="2023-08-11T14:18:43+08:00">2023-08-11</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/hexo/categories/%E9%9D%A2%E7%BB%8F/" itemprop="url" rel="index"><span itemprop="name">面经</span></a>
        </span>
    </span>

  
    <span class="post-meta-item" title="阅读次数" id="busuanzi_container_page_pv">
      <span class="post-meta-item-icon">
        <i class="far fa-eye"></i>
      </span>
      <span class="post-meta-item-text">阅读次数：</span>
      <span id="busuanzi_value_page_pv"></span>
    </span>
    <span class="post-meta-break"></span>
    <span class="post-meta-item" title="本文字数">
      <span class="post-meta-item-icon">
        <i class="far fa-file-word"></i>
      </span>
      <span class="post-meta-item-text">本文字数：</span>
      <span>11k</span>
    </span>
    <span class="post-meta-item" title="阅读时长">
      <span class="post-meta-item-icon">
        <i class="far fa-clock"></i>
      </span>
      <span class="post-meta-item-text">阅读时长 &asymp;</span>
      <span>40 分钟</span>
    </span>
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
        <h1 id="快手一面">快手一面</h1>
<h3 id="重载和重写的区别调用的时候怎么确定调用的是哪个">1、重载和重写的区别？调用的时候怎么确定调用的是哪个？</h3>
<ul>
<li><strong>方法重载</strong>：发生在同一个类中，拥有两个或更多个名称相同但参数列表(参数类型、参数个数)不同的方法，方法的重载与返回值类型无关。</li>
<li><strong>方法重写</strong>：发生在当子类继承父类时，对父类中的一些方法根据自己需求进行重写操作。</li>
</ul>
<p>方法的重写发生在运行时，因为在编译时，编译器无法知道我们到底是调用的父类方法还是子类方法，只有在实际运行的时候才知道应该调用哪个方法，这也是Java运行时多态的体现。</p>
<p>方法的重载发生在编译时，在编译过程中，编译器必须根据参数类型以及长度来确定调用的哪个方法，这也是Java编译时多态的体现。</p>
<span id="more"></span>
<h3 id="java支持多继承吗">2、Java支持多继承吗？</h3>
<p>不支持，Java中一个类只能直接继承一个父类，但是可以实现多个接口。</p>
<h3 id="string类了解吗不可变性表现在哪我如果创建string对象的话改了字符串的值那改变属性的话是不是就变了">3、String类了解吗？不可变性表现在哪？我如果创建String对象的话，改了字符串的值，那改变属性的话是不是就变了？</h3>
<p>String类是java中表示字符串的类，它是不可变的。意味着一旦一个String对象被创建，它的值就不能被改变。如果试图修改一个String对象中的字符，实际上是创建了一个新的String对象，而不是在原来的对象上修改。</p>
<p>String类的不可变性表现在对象创建后其值不能被修改，对String对象进行修改实际上是创建新的对象，因此改变String对象的属性不会改变原对象的值。</p>
<h3 id="string设计为不可变的好处有哪些">4、String设计为不可变的好处有哪些？</h3>
<p>不可变使得String类在多线程环境下更安全，因为多个线程可以同时访问和共享同一个String对象，而不需要担心其被修改。</p>
<p>优化内存，相同的String对象可以被多个引用共享，而不需要产生额外的副本。</p>
<h3 id="java异常体系了解吗error能被捕获吗catch能carch-error吗">Java异常体系了解吗？Error能被捕获吗？Catch能carch Error吗?</h3>
<figure>
<img data-src="https://codeleader.oss-cn-beijing.aliyuncs.com/site/image-20230807215419666.png" alt=""><figcaption>image-20230807215419666</figcaption>
</figure>
<p>Java中的异常主要分为<code>Error</code>和<code>Exception</code></p>
<ul>
<li><strong>Error</strong>:指的是Java虚拟机无法解决的严重问题，一般不编写针对性的代码进行处理。</li>
<li><strong>Exception</strong>：指Java程序运行异常，在运行中的程序发生了程序员不期望发生的事情，可以被Java异常处理机制处理(可以被catc捕获)。</li>
</ul>
<blockquote>
<p><code>RuntimeException</code>:指在Java虚拟机正常运⾏期间抛出的异常，<code>RuntimeException</code>可以被捕获并处理，如果出现此情况，我们需要抛出异常或者捕获并处理异常。常见的有<code>NullPointerException</code>、<code>ClassCastException</code>、 <code>ArrayIndexOutOfBoundsException</code>等。</p>
<p><code>CheckedException</code>:指在编译阶段Java编译器检查<code>CheckedException</code>异常，并强制程序捕获和处理此类异常，要求程序在可能出现异常的地⽅通过<code>try catch</code>语句块捕获异常并处理异常。常见的有由于I/O错误导致的<code>IOException</code>、<code>SQLException</code>、<code>ClassNotFoundException</code>等。该类异常通常由于打开错误的⽂件、<code>SQL</code>语法错误、类不存在等引起。</p>
</blockquote>
<p>不建议使用catch捕获Error,当程序出现Error的时候，通常出现了不可恢复的问题，通常是由JVM或者底层系统引起的，例如内存溢出(OutOfMemoryError)或者栈溢出(StackOverflowError)。</p>
<h3 id="多个线程运行到error的时候只是停一个线程还是这个进程就停了">多个线程运行到Error的时候，只是停一个线程还是这个进程就停了？</h3>
<p>多线程中一个线程出现异常不会影响到线程池里面其他线程的正常执行，这个线程不是被回收了而是线程池把这个线程移除掉，同时创建一个新的线程放到线程池中(不确定正确性)。</p>
<blockquote>
<p>参考：<a target="_blank" rel="noopener" href="https://zhuanlan.zhihu.com/p/136571068#:~:text=%E4%BC%B0%E8%AE%A1%E5%BE%88%E5%A4%9A%E4%BA%BA%E4%BC%9A%E6%98%AF%E4%BB%A5%E4%B8%8B%E4%B8%89%E7%82%B9%E7%AD%94%E6%A1%88%EF%BC%88me%20too%29%3A,1.%E6%8A%9B%E5%BC%82%E5%B8%B8%E5%87%BA%E6%9D%A5%E5%B9%B6%E6%89%93%E5%8D%B0%E5%9C%A8%E6%8E%A7%E5%88%B6%E5%8F%B0%E4%B8%8A%202.%E5%85%B6%E4%BB%96%E7%BA%BF%E7%A8%8B%E4%BB%BB%E5%8A%A1%E4%B8%8D%E5%8F%97%E5%BD%B1%E5%93%8D%203.%E5%BC%82%E5%B8%B8%E7%BA%BF%E7%A8%8B%E4%BC%9A%E8%A2%AB%E5%9B%9E%E6%94%B6">70%人答不全！线程池中的一个线程异常了会被怎么处理?</a></p>
</blockquote>
<h3 id="说说常见的runtimeexception非受检异常">说说常见的RuntimeException(非受检异常)</h3>
<ul>
<li><p><code>NullPointerException</code>(空指针异常)</p></li>
<li><p><code>IllegalArgumentException</code>(参数错误比如方法入参类型异常)</p></li>
<li><p><code>NumberFormatException</code>（字符串转换为数字格式异常,<code>IllegalArgumentException</code>的子类)</p></li>
<li><p><code>ArrayIndexOutOfBoundsException</code>（数组越界异常）</p></li>
<li><p><code>ClassCastException</code>（类型转换异常）</p></li>
<li><p><code>ArithmeticException</code>（算术异常）</p></li>
<li><p><code>SecurityException</code> （安全异常比如权限不够）</p></li>
<li><p><code>UnsupportedOperationException</code>(不支持的操作异常比如重复创建同一用户)</p></li>
<li><p>......</p></li>
</ul>
<h3 id="有处理过编译时异常吗">有处理过编译时异常吗？</h3>
<p><code>CheckedException</code>即受检查异常，Java代码在编译过程中，如果受检查异常没有被<code>catch</code>或者throws关键词处理的话，就没办法通过编译。</p>
<p><code>IOException</code>、<code>SQLException</code>、<code>ClassNotFoundException</code>、<code>SQLException</code></p>
<h3 id="io操作的异常是不是必须要捕获">I/O操作的异常是不是必须要捕获？</h3>
<p>必须捕获，IOException属于受检异常(CheckedException)，必须在代码中显示地进行处理，佛祖额会导致编译错误。</p>
<h3 id="java的反射了解吗">Java的反射了解吗？</h3>
<p><strong>反射机制</strong>是在程序运行中，对任意一个类都能获取其所有属性和方法，并且对任意对象都能调用其任意方法。这种动态获取类和对象的信息，以及动态调用对象的方法的功能被称为Java的反射机制。</p>
<p>Java获取Class对象的三种方式</p>
<ul>
<li>调用某个对象的<code>getClass</code>方法</li>
<li>调用某个类的<code>class</code>属性</li>
<li>调用Class类中的<code>forName</code>静态方法</li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">Person p=<span class="keyword">new</span> <span class="title class_">Person</span>();</span><br><span class="line"><span class="comment">//调用getClass方法</span></span><br><span class="line">Class c1=p.getClass();</span><br><span class="line"><span class="comment">//调用类的class属性</span></span><br><span class="line">Class c2=Person.class;</span><br><span class="line"><span class="comment">//调用Class类中的forName静态方法</span></span><br><span class="line">Class c3=Class.forName(<span class="string">"com.company"</span>)<span class="comment">//(完整包路径及名称)</span></span><br></pre></td></tr></table></figure>
<blockquote>
<p>因为一个类在<code>JVM</code>中只会有一个<code>Class</code>实例，所以对<code>c1、c2、c3</code>进行<code>equals</code>比较时返回的都是<code>true</code>。</p>
</blockquote>
<h3 id="用反射的时候如果一个类是私有的有一个私有的属性能用反射修改这个值吗">用反射的时候，如果一个类是私有的，有一个私有的属性，能用反射修改这个值吗？</h3>
<h3 id="用过hashmap看过底层数据结构吗">用过HashMap？看过底层数据结构吗？</h3>
<p>HashMap根据键的hashCode值存放数据，大多数情况下可以直接定位到它的值，因而具有很快的访问速度，但遍历顺序却是不确定的。如果多个键具有相同的哈希值，则可能发生哈希碰撞，HashMap使用链表或红黑树的形式解决哈希碰撞，当多个键具有相同的哈希值时，它们会被存储在痛殴过一个索引位置处的链表或红黑树中。</p>
<blockquote>
<p>HashMap最多只允许一条记录的键为null，允许多条记录的值为null</p>
<p>HashMap非线程安全，可以使用<code>Collections</code>的<code>synchronizedMap</code>方法使HashMap具有线程安全的能力</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">HashMap&lt;Object, Object&gt; map = <span class="keyword">new</span> <span class="title class_">HashMap</span>&lt;&gt;();</span><br><span class="line">Map&lt;Object, Object&gt; synchronizedMap = Collections.synchronizedMap(map);</span><br></pre></td></tr></table></figure>
<p>或者使用<code>ConcurrentHashMap</code>。</p>
</blockquote>
<p>Jdk7及之前的HashMap结构：<strong>数组+链表</strong></p>
<figure>
<img data-src="https://codeleader.oss-cn-beijing.aliyuncs.com/site/image-20230708164303190.png" alt=""><figcaption>image-20230708164303190</figcaption>
</figure>
<p>JDK1.8的HashMap结构：<strong>数据+链表+红黑树</strong></p>
<figure>
<img data-src="https://codeleader.oss-cn-beijing.aliyuncs.com/site/image-20230708164340649.png" alt=""><figcaption>image-20230708164340649</figcaption>
</figure>
<h3 id="hashmap是线程安全的吗哪些地方会发生线程不安全待补充">HashMap是线程安全的吗？哪些地方会发生线程不安全(待补充)？</h3>
<p>HashMap不是线程安全的，插入数据的时候可能发生数据覆盖的情况。</p>
<h3 id="threadlocal用过吗它是怎么解决线程安全的结构了解吗">ThreadLocal用过吗？它是怎么解决线程安全的？结构了解吗？</h3>
<p>通常情况下，我们创建的变量可以被任何一个线程访问并修改。如果想实现每一个线程都有自己的专属本地变量该如何解决？JDK自带的<code>ThreadLocal</code>正是为了解决这个问题。</p>
<p><code>ThreadLocal</code>类主要解决的是让每个线程绑定自己的值，可以将ThreadLocal类形象的比喻成存放数据的盒子，盒子中可以存储每个线程的私有数据。</p>
<p>如果你创建了一个ThreadLocal变量，那么访问这个变量的每个线程都会有这个变量的本地副本，它们可以使用get()和set()方法来获取默认值或将其值更改为当前线程所存的副本的值，从而避免了线程安全问题。</p>
<figure>
<img data-src="https://codeleader.oss-cn-beijing.aliyuncs.com/site/image-20230808111612153.png" alt=""><figcaption>image-20230808111612153</figcaption>
</figure>
<h3 id="concurrenthashmap是通过什么方式实现的线程安全">ConcurrentHashMap是通过什么方式实现的线程安全？</h3>
<p><code>ConcurrentHashMap</code>是HashMap中支持高并发、高吞吐量的线程安全的版本。它由<code>Segment</code>数组结构和<code>HashEntry</code>数组结构组成。Segment在ConcurrentHashMap中扮演锁的角色，HashEntry则用于存储键值对数据。</p>
<p><strong>JDK1.7中ConcurrentHashMap实现</strong>：JDK1.7中ConcurrentHashMap采用分段锁的思想实现并发操作，因此是线程安全的。ConcurrentHashMap有多个Segment组成(Segment的数量也是锁的并发度)，每个Segment均继承于ReentrantLock并单独加锁，所以每次进行加锁操作时锁住的都是一个Segment，这样只要保证每个Segment都是线程安全的，也就实现了全局的线程安全。</p>
<figure>
<img data-src="https://codeleader.oss-cn-beijing.aliyuncs.com/site/image-20230708174345789.png" alt=""><figcaption>image-20230708174345789</figcaption>
</figure>
<p><strong>JDK1.8中ConcurrentHashMap的实现</strong>：JDK1.8中ConcurrentHashMap弃用了Segment分段锁，改用<code>Synchronized+CAS</code>实现对多线程的安全操作。同时，JDK1.8在ConcurrentHashMap中引入了红黑树。</p>
<p>Java8中，锁粒度更细，<code>synchronized</code> 只锁定当前链表或红黑二叉树的首节点，这样只要hash不冲突，就不会产生并发，就不会影响其他Node的读写，效率大幅提升。</p>
<figure>
<img data-src="https://codeleader.oss-cn-beijing.aliyuncs.com/site/image-20230708174317589.png" alt=""><figcaption>image-20230708174317589</figcaption>
</figure>
<h3 id="线程池用过吗创建线程的常用参数有哪些拒绝策略">线程池用过吗？创建线程的常用参数？有哪些拒绝策略？</h3>
<p>线程池的主要作用是线程复用、线程资源管理、控制操作系统的最大并发数，以保证系统高效(通过线程资源复用)和安全(通过控制最大并发线程数)的运行。</p>
<p><strong>Java线程池的原理</strong>：JVM先根据用户的参数创建一定数量的可运行的线程任务，并将其放入队列中，在线程创建后启动这些任务，如果正在运行的线程数量超过了最大线程数(用户设置的线程池大小)，则超出数量的线程排队等候，在有任务执行完毕后，线程池调度器会发现可用的线程，进而再次从队列中取出任务并执行。</p>
<p>使用线程池可以降低资源消耗、提高响应速度、提高线程的可管理性。</p>
<p>线程池的参数如下：</p>
<ul>
<li><code>corePoolSize</code>：线程池中核心线程数。</li>
<li><code>maximumPoolSize</code>：线程池中最大线程数。</li>
<li><code>keepAliveTime</code>:当前线程数量大于核心线程数时，空闲线程的等待时间。</li>
<li><code>unit</code>:keepAliveTime的时间单位</li>
<li><code>workQueue</code>:任务队列，被提交但尚未被执行的任务存放的地方。</li>
<li><code>threadFactory</code>:线程工厂，用于创建线程，可使用默认的线程工厂或自定义线程工厂。</li>
<li><code>handler</code>:拒绝策略：由于任务过多或其他原因导致线程池无法处理时的任务拒绝策略。</li>
</ul>
<p>拒绝策略：</p>
<p>如果线程池中的核心线程被用完且阻塞队列已满，则此时线程池的线程资源已耗尽，线程池没有足够的线程资源执行新的任务。为了保证操作系统的安全，线程池将通过拒绝策略处理新添加的线程任务。</p>
<ul>
<li><code>AbortPoliccy</code>:直接抛出异常，阻止线程正常运行。</li>
<li><code>CallerRunsPolicy</code>:如果被丢弃的线程任务未关闭，则执行该线程任务。</li>
<li><code>DiscardOldestPolicy</code>:移除线程队列中最早的一个线程任务，并尝试提交当前任务。</li>
<li><code>DiscardPolicy</code>:丢弃当前的线程任务而不做任何处理。</li>
<li>自定义拒绝策略：自己扩展RejectedExecutionHandler接口来实现拒绝策略，并捕获异常来实现自定义拒绝策略。</li>
</ul>
<p>创建线程池的方法：通过<strong>Executors工厂方法创建</strong>和通过<strong>new ThreadPoolExecutor方法</strong>创建</p>
<ul>
<li><p><code>Execurots</code>工厂方法创建，在工具类Execurots提供了一些静态的工厂方法</p>
<p>newFixedThreadPool:创建固定大小的线程池。</p>
<p>newCachedThreadPool:创建一个带缓冲的线程池。</p>
<p>newSingleThreadExecutor:创建一个单线程的线程池</p>
<p>newScheduledThreadPool:调度线程池，可以按照一定的周期执行任务，即定时任务.</p></li>
<li><p>new ThreadPoolExecutor创建：</p></li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">new</span> <span class="title class_">ThreadPoolExecutor</span>(<span class="type">int</span> corePoolSize,				<span class="comment">//核心线程数</span></span><br><span class="line">                       <span class="type">int</span> maximumPoolSize,		<span class="comment">//最大线程数</span></span><br><span class="line">                       <span class="type">long</span> keepAliveTime,		</span><br><span class="line">                       TimeUnit unit,</span><br><span class="line">                       BlockingQueue&lt;Runnable&gt; workQueue,	<span class="comment">//存放任务的阻塞队列</span></span><br><span class="line">                       ThreadFactory threadFactory,		<span class="comment">//为线程池提供创建新线程的线程工厂</span></span><br><span class="line">                       RejectedExecutionHandler handler)<span class="comment">//拒绝策略</span></span><br></pre></td></tr></table></figure>
<h3 id="线程通信方式待补充">线程通信方式(待补充)</h3>
<ul>
<li>共享变量：多个线程通过共享变量来进行通信。线程可以通过读写共享变量来传递数据。对于共享变量的访问需要加上同步机制，如<strong>synchronized</strong>关键字或<strong>Lock</strong>接口，以确保线程安全。</li>
<li>等待通知机制：可以使用wait()和notify()或者wait()和notifyAll()方法实现线程间的等待和唤醒操作，以便在特定条件下进行通信。</li>
<li>互斥锁：互斥锁用于保护共享资源，确保只有一个线程可以访问该资源，Java中可以使用<strong>ReentrantLock</strong>类来实现互斥锁。</li>
<li>管道输入/输出流：Java提供了PipedInputStream和PipedOutputStream类，可以在两个相关联的线程之间进行数据传递。一个线程将数据写入PipedOutputStream,另一个线程则从相应的PipedInputStream中读取数据。</li>
<li>条件变量(Condition):条件变量用于在线程之间传递信息，以及在特定条件下进行等待和唤醒。Java中，<code>ReentrantLock</code> 类配合 <code>Condition</code> 接口可以实现条件变量。</li>
<li>并发集合：Java中提供了多种线程安全的集合类，如ConcurrentHashMap、ConcurrentLinkedQueue等，它们可以在多线程环境下安全地操作数据。</li>
</ul>
<h3 id="看你有实习经历和项目经历之前处理线程池的拒绝策略用什么措施处理的那任务数多了的话能知道哪个业务触发的吗">看你有实习经历和项目经历，之前处理线程池的拒绝策略用什么措施处理的？那任务数多了的话能知道哪个业务触发的吗？</h3>
<h3 id="你对synchronized关键字的理解">你对Synchronized关键字的理解</h3>
<p>在多线程的环境下，多个线程同时访问共享资源会出现一些问题，而synchronized关键字是用来保证线程同步的，可以保证它修饰的方法或者代码块在任意时刻只能有一个线程执行。</p>
<p>synchronized关键字的三大特性如下：</p>
<ul>
<li>原子性：一个或多个操作要么全部执行成功，要么全部执行失败，synchronized关键字可以保证只有一个线程拿到锁，访问共享资源。</li>
<li>可见性：当一个线程对共享变量进行修改后，其他线程可以立刻看到。执行synchronized时，会对应执行lock、unlock原子操作，保证可见性。</li>
<li>有序性：程序的执行顺序会按照代码的先后顺序执行。</li>
</ul>
<blockquote>
<p>synchronized可以保证并发编程的三大特性：原子性、可见性、有序性，而volatile关键字只能保证可见性和有序性。</p>
</blockquote>
<h3 id="了解锁的优化吗jdk1.6之后对锁进行了大量的优化你了解吗">了解锁的优化吗？JDK1.6之后对锁进行了大量的优化，你了解吗？</h3>
<p>在JDK1.6中，为了减少获得锁和释放锁带来的性能损耗，引入了偏向锁和轻量级锁，所得状态变成了四种，无锁状态、偏向锁状态、轻量级锁和重量级锁状态。锁的状态会随着竞争激烈逐渐升级，但通常情况下，锁的状态只能升级不能降级。</p>
<h3 id="reentrantlock了解吗和synchronized有什么区别是公平锁吗">ReentrantLock了解吗？和synchronized有什么区别？是公平锁吗？</h3>
<p><strong>ReentrantLock(可重入锁)</strong>实现了Lock接口,是一个可重入且独占式的锁，和<code>synchronized</code>关键字类似，不过ReentrantLock更灵活、强大，增加了轮询、超时、中断、公平锁和非公平锁等高级功能。</p>
<blockquote>
<p><strong>重入锁</strong>，是指在同一线程中，外部方法获得锁之后，内层递归方法依然可以获得该锁，如果锁不具备重入性，那么当同一个线程两次获取锁的时候就会发生死锁。</p>
</blockquote>
<p>ReentrantLock默认使用非公平锁，也可以通过构造器显示指定非公平锁。</p>
<ul>
<li><strong>公平锁</strong>：锁被释放之后，先申请的线程先得到锁。性能较差，公平锁为了保证时间上的绝对顺序，上下文切换更频繁。</li>
<li><strong>非公平锁</strong>：锁被释放之后，后申请的线程可能会先获取到锁，是随机或者按照其他优先级排序的。性能更好，单可能会导致某些线程无法获取到锁。</li>
</ul>
<p><strong>synchronized与ReentrantLock的异同</strong></p>
<ul>
<li><p>两者都是可重入锁</p></li>
<li><p>synchronized依赖于JVM而ReentrantLock依赖于API</p>
<p><code>synchronized</code>是依赖于JVM的，而<code>ReentrantLock</code>是JDK层面实现的也就是API层面，需要lock()和unlock()方法配合try/finally语句块来完成。</p></li>
<li><p>synchronized不需要用户手动释放锁，ReentrantLock则需要用户手动释放锁。</p></li>
<li><p>ReentrantLock比synchronized增加了一些高级功能：</p>
<p><strong>等待可中断</strong> : <code>ReentrantLock</code>提供了一种能够中断等待锁的线程的机制，通过 <code>lock.lockInterruptibly()</code> 来实现这个机制。也就是说正在等待的线程可以选择放弃等待，改为处理其他事情。</p>
<p><strong>可实现公平锁</strong> : <code>ReentrantLock</code>可以指定是公平锁还是非公平锁。而<code>synchronized</code>只能是非公平锁。所谓的公平锁就是先等待的线程先获得锁。<code>ReentrantLock</code>默认情况是非公平的，可以通过 <code>ReentrantLock</code>类的<code>ReentrantLock(boolean fair)</code>构造方法来制定是否是公平的。</p>
<p><strong>可实现选择性通知（锁可以绑定多个条件）</strong>: <code>synchronized</code>关键字与<code>wait()</code>和<code>notify()</code>/<code>notifyAll()</code>方法相结合可以实现等待/通知机制。<code>ReentrantLock</code>类当然也可以实现，但是需要借助于<code>Condition</code>接口与<code>newCondition()</code>方法。</p></li>
</ul>
<h3 id="单例设计模式了解吗怎么实现的">单例设计模式了解吗？怎么实现的？</h3>
<p>单例模式是保证系统实例唯一性的重要手段。单例模式首先通过将类的实例化方法私有化来防止程序通过其他方法创建该类的实例，然后通过一个全局唯一获取该类实例的方法帮助用户获取类的实例。</p>
<p>单例模式保证了一个类在整个系统中同一时刻只有一个实例存在，主要被用于一个全局类的对象在多个地方被使用且对象的状态是全局变化的场景下。</p>
<blockquote>
<p>单例模式的常见模式有<strong>懒汉模式(线程安全)、饿汉模式、静态内部类、双重校验锁</strong>。</p>
</blockquote>
<ol type="1">
<li>懒汉式(线程安全)：</li>
</ol>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//懒汉模式(线程安全)</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">LazySingleton</span> {</span><br><span class="line">    <span class="keyword">private</span>  <span class="keyword">static</span> LazySingleton instance;</span><br><span class="line">    <span class="keyword">private</span> <span class="title function_">LazySingleton</span><span class="params">()</span>{}</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">synchronized</span> LazySingleton <span class="title function_">getInstance</span><span class="params">()</span>{</span><br><span class="line">        <span class="keyword">if</span>(instance==<span class="literal">null</span>){</span><br><span class="line">            instance=<span class="keyword">new</span> <span class="title class_">LazySingleton</span>();</span><br><span class="line">        }</span><br><span class="line">        <span class="keyword">return</span> instance;</span><br><span class="line">    }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>(2)饿汉式</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//饿汉式</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">HungrySingleton</span> {</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> HungrySingleton instance=<span class="keyword">new</span> <span class="title class_">HungrySingleton</span>();</span><br><span class="line">    <span class="keyword">private</span> <span class="title function_">HungrySingleton</span><span class="params">()</span>{}</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> HungrySingleton <span class="title function_">getInstance</span><span class="params">()</span>{</span><br><span class="line">        <span class="keyword">return</span> instance;</span><br><span class="line">    }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>(3)静态内部类</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//静态内部类</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Singleton</span> {</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">class</span> <span class="title class_">SingletonHolder</span>{</span><br><span class="line">        <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> Singleton INSTANCE=<span class="keyword">new</span> <span class="title class_">Singleton</span>();</span><br><span class="line">    }</span><br><span class="line">    <span class="keyword">private</span> <span class="title function_">Singleton</span><span class="params">()</span>{}</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">final</span> Singleton <span class="title function_">getInstance</span><span class="params">()</span>{</span><br><span class="line">        <span class="keyword">return</span> SingletonHolder.INSTANCE;</span><br><span class="line">    }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>（4）双重校验锁</p>
<blockquote>
<p>双锁模式在懒汉模式的基础上作了进一步优化，<strong>给静态对象的定义加上<code>volatile</code>来保障初始化时对象的唯一性，在获取对象时通过<code>synchronized(Singleton.class)</code>给单例类加锁来保障操作的唯一性</strong>。</p>
</blockquote>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//双重校验锁</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Lock2Singleton</span> {</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">volatile</span> <span class="keyword">static</span> Lock2Singleton singleton;   <span class="comment">//1:对象锁</span></span><br><span class="line">    <span class="keyword">private</span> <span class="title function_">Lock2Singleton</span><span class="params">()</span>{}</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> Lock2Singleton <span class="title function_">getSingleton</span><span class="params">()</span>{</span><br><span class="line">        <span class="keyword">if</span>(singleton==<span class="literal">null</span>){</span><br><span class="line">            <span class="keyword">synchronized</span> (Lock2Singleton.class){     <span class="comment">//2:synchronized方法锁</span></span><br><span class="line">                <span class="keyword">if</span>(singleton==<span class="literal">null</span>){</span><br><span class="line">                    singleton=<span class="keyword">new</span> <span class="title class_">Lock2Singleton</span>();</span><br><span class="line">                }</span><br><span class="line">            }</span><br><span class="line">        }</span><br><span class="line">        <span class="keyword">return</span> singleton;</span><br><span class="line">    }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<blockquote>
<p>第一次<code>if(singleton==null)</code>：为了提高代码的执行效率，由于单例模式只要一次创建实例即可，所以当创建了一个实例之后，再次调用<code>getInstance</code>方法就不用进入同步代码块，不用竞争锁。</p>
<p>第二次<code>if(singleton==null)</code>：这个校验时防止二次创建实例。</p>
</blockquote>
<h3 id="mysql常用的索引结构有哪些">MySQL常用的索引结构有哪些？</h3>
<h3 id="b树的每个索引都会存储每一行的记录吗">B+树的每个索引都会存储每一行的记录吗？</h3>
<h3 id="并发事务带来了哪些问题">并发事务带来了哪些问题？</h3>
<p><strong>(1)脏读</strong>：事务A更新了数据，但还没有提交，这时事务B读取到事务A更新后的数据，然后事务A回滚了，事务B读取到的数据就称为脏数据了。</p>
<figure>
<img data-src="https://codeleader.oss-cn-beijing.aliyuncs.com/site/image-20230801155155628.png" alt=""><figcaption>image-20230801155155628</figcaption>
</figure>
<p><strong>(2)不可重复读</strong>：事务A对数据进行多次读取，事务B在事务A多次读取的过程中执行了更新操作并提交了，导致事务A多次读取到的数据不一致。</p>
<figure>
<img data-src="https://codeleader.oss-cn-beijing.aliyuncs.com/site/image-20230801155454797.png" alt=""><figcaption>image-20230801155454797</figcaption>
</figure>
<p><strong>(3)幻读</strong>：事务A在读取数据后，事务B向事务A读取的数据中插入了几条数据，事务A再次读取数据时发现多了几条数据，和之前读取的数据不一致。</p>
<figure>
<img data-src="https://codeleader.oss-cn-beijing.aliyuncs.com/site/image-20230801155747152.png" alt=""><figcaption>image-20230801155747152</figcaption>
</figure>
<p><strong>(4)丢失修改</strong>：事务A和事务B都对同一个数据进行修改，事务A先修改，事务B后修改，事务B的修改覆盖了事务A的修改。</p>
<figure>
<img data-src="https://codeleader.oss-cn-beijing.aliyuncs.com/site/image-20230801155910501.png" alt=""><figcaption>image-20230801155910501</figcaption>
</figure>
<blockquote>
<p><strong>不可重复度和幻读的区别</strong>：在不可重复读中，发现数据的不一致主要是数据被更新了。在幻读中，发现数据不一致主要是数据增多或者减少了。</p>
</blockquote>
<h3 id="mysql的事务隔离级别有哪些每种隔离级别可能会产生哪些问题">MySQL的事务隔离级别有哪些？每种隔离级别可能会产生哪些问题？</h3>
<ul>
<li><strong>读未提交(Read Uncommitted)</strong>：最低的隔离级别，允许读取尚未提交的数据变更，可能导致<strong>脏读、幻读和不可重复读</strong>。</li>
<li><strong>读已提交(Read Committed)</strong>：允许读取并发事务已经提交的数据，可以阻止脏读，但可能导致<strong>幻读</strong>和<strong>不可重复读</strong>。</li>
<li><strong>可重复读(Repeatable Read)</strong>：对同一字段的多次读取结果是一致的，除非数据是被本身事务自己所修改，可以阻止脏读和不可重复读，可能导致<strong>幻读</strong>。</li>
<li><strong>可串行化(Serializable)</strong>：最高的隔离级别，完全服从ACID的隔离级别，所有的事务依次逐个执行，这样事务之间就不会产生干扰，该级别可以防止脏读、不可重复读和幻读。</li>
</ul>
<figure>
<img data-src="https://codeleader.oss-cn-beijing.aliyuncs.com/site/image-20230801163556062.png" alt=""><figcaption>image-20230801163556062</figcaption>
</figure>
<h3 id="aop思想是什么原理了解吗底层是怎么实现的">AOP思想是什么？原理了解吗？底层是怎么实现的？</h3>
<p>AOP(Aspect-Oriented Programming:面向切面编程)能够将那些与业务无关，却为业务模块所共同调用的逻辑或责任（例如事务处理、日志管理、权限控制等）封装起来，便于减少系统的重复代码，降低模块间的耦合度，并有利于未来的可拓展性和可维护性。</p>
<p>Spring AOP就是基于动态代理的，如果要代理的对象，实现了某个接口，那么Spring AOP会使用 <strong>JDK Proxy</strong>，去创建代理对象，而对于没有实现接口的对象，就无法使用JDK Proxy去进行代理了，这时候Spring AOP会使用 <strong>Cglib</strong> 生成一个被代理对象的子类来作为代理，如下图所示：</p>
<p><img data-src="https://codeleader.oss-cn-beijing.aliyuncs.com/site/230ae587a322d6e4d09510161987d346.jpeg"></p>
<h3 id="jdk动态代理了解吗">JDK动态代理了解吗？</h3>
<p><strong>从 JVM 角度来说，动态代理是在运行时动态生成类字节码，并加载到 JVM 中的。</strong></p>
<p>说到动态代理，Spring AOP、RPC框架应该是两个不得不提的，它们的实现都依赖了动态代理。</p>
<p><strong>动态代理在我们日常开发中使用的相对较少，但是在框架中的几乎是必用的一门技术。学会了动态代理之后，对于我们理解和学习各种框架的原理也非常有帮助。</strong></p>
<p>就Java来说，动态代理的实现方式有很多种，比如 <strong>JDK 动态代理</strong>、<strong>CGLIB 动态代理</strong>等等。</p>
<p><strong>在 Java 动态代理机制中 <code>InvocationHandler</code> 接口和 <code>Proxy</code> 类是核心。</strong></p>
<p><code>Proxy</code> 类中使用频率最高的方法是：<code>newProxyInstance()</code> ，这个方法主要用来生成一个代理对象。</p>
<figure>
<img data-src="https://codeleader.oss-cn-beijing.aliyuncs.com/site/image-20230808164719217.png" alt=""><figcaption>image-20230808164719217</figcaption>
</figure>
<ul>
<li>loader:类加载器，用于加载代理对象</li>
<li>interfaces:被代理类实现的一些接口</li>
<li>h:实现了InvocationHandler接口的对象</li>
</ul>
<p>要实现动态代理的话，还必须需要实现<code>InvocationHandler</code> 来自定义处理逻辑。 当我们的动态代理对象调用一个方法时，这个方法的调用就会被转发到实现<code>InvocationHandler</code> 接口类的 <code>invoke</code> 方法来调用。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">interface</span> <span class="title class_">InvocationHandler</span> {</span><br><span class="line">     <span class="comment">//当你使用代理对象调用方法的时候实际会调用到这个方法</span></span><br><span class="line">    <span class="keyword">public</span> Object <span class="title function_">invoke</span><span class="params">(Object proxy, Method method, Object[] args)</span></span><br><span class="line">        <span class="keyword">throws</span> Throwable;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<ul>
<li>proxy:动态生成的代理类</li>
<li>method:与代理类对象调用的方法相对应</li>
<li>args:当前method方法的参数</li>
</ul>
<p>也就是说：<strong>你通过<code>Proxy</code> 类的 <code>newProxyInstance()</code> 创建的代理对象在调用方法的时候，实际会调用到实现<code>InvocationHandler</code> 接口的类的 <code>invoke()</code>方法。</strong> 你可以在 <code>invoke()</code> 方法中自定义处理逻辑，比如在方法执行前后做什么事情。</p>
<p>JDK动态代理使用步骤：</p>
<p>(1)定义一个接口及其实现类；</p>
<p>(2)自定义<code>InvocationHandler</code>并重写<code>invoke</code>方法，在<code>invoke</code>方法中我们会调用原生方法（被代理类的方法）并自定义一些处理逻辑；</p>
<p>(3)通过<code>Proxy.newProxyInstance(ClassLoader loader,Class&lt;?&gt;[] interfaces,InvocationHandler h)</code>方法创建代理对象；</p>
<blockquote>
<p>IDEA上例子</p>
</blockquote>
<h3 id="redis的数据结构有哪些">Redis的数据结构有哪些？</h3>
<h3 id="zset的底层数据结构是什么跳表了解吗">ZSet的底层数据结构是什么？跳表了解吗？</h3>
<p><strong>skipList(跳表)</strong>首先是链表，但与传统链表相比有几点差异：</p>
<ul>
<li>元素按照升序排列存储</li>
<li>节点可能包含多个指针，指针跨度不同。</li>
</ul>
<figure>
<img data-src="https://codeleader.oss-cn-beijing.aliyuncs.com/site/image-20230808152038722.png" alt=""><figcaption>image-20230808152038722</figcaption>
</figure>
<figure>
<img data-src="https://codeleader.oss-cn-beijing.aliyuncs.com/site/image-20230808153322054.png" alt=""><figcaption>image-20230808153322054</figcaption>
</figure>
<p><strong>SkipList的特点：</strong></p>
<ul>
<li>跳表是一个双向链表，每个节点都包含score和ele值</li>
<li>节点按照score值排序,score值一样则按照ele字典排序</li>
<li>每个节点都可以包含多层指针，层数是1到32之间的随机数</li>
<li>不同层指针到下一个节点的跨度不同，层级越高，跨度越大</li>
<li>增删改查效率与红黑树一致，实现却更简单</li>
</ul>
<h3 id="redis的持久化策略">Redis的持久化策略</h3>
<p>Redis是基于内存的，为了防止一些意外情况导致数据丢失，需要将数据持久化到磁盘上。</p>
<p>Redis提供了两种持久化方式，一种是<strong>RDB</strong>，一种是<strong>AOF</strong>。</p>
<p><strong>(1)RDB(Redis Database)</strong></p>
<p>RDB时Redis的默认持久化方式，按照一定的时间间隔将内存的数据以快照的形式保存到磁盘，恢复时是将快照读取到内存中。RDB持久化实际操作过程是fork一个子进程，先将数据集写入临时文件，写入成功后，再替换之前的文件，用二进制压缩存储，如下图。</p>
<figure>
<img data-src="https://codeleader.oss-cn-beijing.aliyuncs.com/site/image-20230803171654565.png" alt=""><figcaption>image-20230803171654565</figcaption>
</figure>
<p><strong>优点：</strong></p>
<ul>
<li>适合对大规模的数据恢复，比AOF的启动效率高</li>
<li>只有一个文件dump.rdb，方便持久化</li>
<li>性能最大化，再开始持久化时，它唯一需要做的只是fork出子进程，之后再由子进程完成这些持久化的工作，这样就可以极大的避免服务进程执行IO操作了。</li>
</ul>
<p><strong>缺点：</strong></p>
<ul>
<li>数据安全性低，在一定间隔时间内做一次备份，如果Redis突然宕机，会丢失最后依次快照的修改</li>
<li>由于RDB是通过fork子进程来协助完成数据持久化工作的，因此当数据集较大时，可能会导致整个服务器停止服务几百毫秒，甚至是1秒钟。</li>
</ul>
<p><strong>(2)AOF(Append-only File)</strong></p>
<p>AOF持久化以日志的形式记录服务器所处理的每一个写、删除操作，查询操作不会记录，以文本的方式记录，可以打开文件看到详细的操作记录。</p>
<figure>
<img data-src="https://codeleader.oss-cn-beijing.aliyuncs.com/site/image-20230803172257557.png" alt=""><figcaption>image-20230803172257557</figcaption>
</figure>
<p><strong>优点：</strong></p>
<ul>
<li>具备更高的安全性，Redis提供了3种同步策略，粉笔是每秒同步、每修改同步和不同步。相比RDB突然宕机丢失的数据会更少，每秒同步会丢失一秒钟的数据，每修改同步不会丢失数据。</li>
<li>由于该机制对日志文件的写入操作采用的是append模式，因此在写入过程中即使出现宕机现象，也不会破坏日志文件中已经存在的内容。</li>
<li>AOF包含一个格式清晰、易于理解的日志文件用于记录所有的修改操作，可以通过该文件完成数据的重建。</li>
</ul>
<p><strong>缺点：</strong></p>
<ul>
<li>对于相同数量的数据集而言，AOF文件通常要大于RDB文件。RDB在恢复大数据集时的速度比AOF快。</li>
<li>根据AOF选择同步策略的不同，效率也不同，但AOF在运行效率上往往会慢于RDB。</li>
</ul>
<h3 id="键的过期删除策略">键的过期删除策略</h3>
<p>常见的过期删除策略是<strong>惰性删除</strong>、<strong>定期删除</strong>、<strong>定时删除</strong>。</p>
<ul>
<li><p><strong>惰性删除</strong>：只有访问这个键时才会检查它是否过期，如果过期则清除。</p>
<p>优点：最大化地节约CPU资源。缺点：如果大量过期键没有被访问，会一致占用大量内存。</p></li>
<li><p><strong>定时删除</strong>：为每个设置过期时间的key都创造一个定时器，到了过期时间就清除。</p>
<p>优点：可以立即清除过期的键。缺点：会占用大量的CPU资源去处理过期的数据。</p></li>
<li><p><strong>定期删除</strong>：每隔一段时间就对一些键进行检查，删除其中过期的键。该策略是惰性删除和定时删除的一个折中，既避免了占用大量CPU资源又避免了出现大量过期键不被清除占用内存的情况。</p></li>
</ul>
<p>Redis中同时使用了<strong>惰性删除</strong>和<strong>定期删除</strong>两种。</p>
<h3 id="redis实现分布式锁">Redis实现分布式锁</h3>
<ul>
<li><strong>获取锁</strong>：使用<code>setnx</code>命令，在获取锁时调用<code>setnx</code>，如果返回0，则该锁正在被别人使用；如果返回1，则成功获取锁。为了释放锁，应当用<code>expire</code>命令设置锁过期时间。</li>
<li><strong>释放锁</strong>：如果锁存在，则执行Redis的<code>del</code>命令。</li>
</ul>
<p>如果在<code>setnx</code>执行之后执行<code>expire</code>之前进程意外crash或者要重启维护了，那这个锁就释放不了。这时应该使用<code>set</code>命令，set命令有非常复杂的参数，相当于合成了<code>setnx</code>和<code>expire</code>两条命令。</p>
<blockquote>
<p>实际可能Redisson或者Zookeeperf实现的分布式锁用的多一点</p>
</blockquote>
<h3 id="项目中有用过redis吗">项目中有用过Redis吗？</h3>
<h3 id="消息队列用过吗你觉得为什么要引入消息队列呢举几个应用场景">消息队列用过吗？你觉得为什么要引入消息队列呢？举几个应用场景</h3>
<blockquote>
<p>需要给出具体的场景</p>
</blockquote>
<ul>
<li>异步处理</li>
<li>应用解耦</li>
<li>流量削峰</li>
</ul>
<h3 id="来一道算法题吧是个气温的题目单调栈">来一道算法题吧？(是个气温的题目，单调栈)</h3>
<hr>
<h3 id="jvm内存模型类加载机制双亲委派模型垃圾回收算法新生代回收策略">JVM内存模型、类加载机制、双亲委派模型、垃圾回收算法、新生代回收策略</h3>
<h3 id="你了解哪些锁">你了解哪些锁？</h3>
<h3 id="java并发关键字">Java并发关键字</h3>
<h4 id="volatile">volatile</h4>
<p>Java除了使用synchronized保证变量的同步，还是用了稍弱的同步机制，即volatile。volatile也用于确保将变量的更新操作通知到其他线程。</p>
<p>使用volatile关键字修饰的变量叫做volatile变量，volatile具备两种特性:</p>
<ul>
<li>保证变量对所有线程可见，在一个线程修改了变量的值后，新的值对于其他线程是可以立即获取的。</li>
<li>禁止指令重排，即volatile变量不会被缓存在寄存器种或者对其他处理器不可见的地方，因此在读取volatile变量时总会返回最新写入的值。</li>
</ul>
<p>在访问volatile变量时不会进行加锁操作，也就不会执行线程阻塞，因此volatile是一种比synchronized更轻量级的同步机制，主要适用于一个变量被多个线程共享，多个线程均可针对这个变量执行赋值或者读取操作。</p>
<p><strong><code>volatile</code>关键字能保证变量的可见性，但不能保证对变量的操作是原子性的。</strong></p>
<p>注意：<strong>volatile可以严格保证变量的单次读、写操作的原子性，并不能保证像<code>i++</code>这种操作的原子性，因为<code>i++</code>在本质上是读、写两次操作</strong>。</p>
<figure>
<img data-src="https://codeleader.oss-cn-beijing.aliyuncs.com/site/image-20230810165036137.png" alt=""><figcaption>image-20230810165036137</figcaption>
</figure>
<h4 id="countdownlatch倒计时器">CountDownLatch(倒计时器)</h4>
<p>CountDownLatch位于<code>java.util.concurrent</code>包下，是一个同步工具类，<strong>基于线程计数器来实现并发访问控制，允许一个或多个线程一起等待其他线程的操作执行完毕后再执行相关操作</strong>。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">CountDownLatchTest</span> {</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> <span class="keyword">throws</span> InterruptedException {</span><br><span class="line">        <span class="keyword">final</span> <span class="type">CountDownLatch</span> <span class="variable">latch</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">CountDownLatch</span>(<span class="number">2</span>);</span><br><span class="line">        <span class="keyword">new</span> <span class="title class_">Thread</span>(()-&gt;{</span><br><span class="line">            System.out.println(<span class="string">"子线程1正在执行"</span>);</span><br><span class="line">            <span class="keyword">try</span> {</span><br><span class="line">                Thread.sleep(<span class="number">3000</span>);</span><br><span class="line">            } <span class="keyword">catch</span> (InterruptedException e) {</span><br><span class="line">                <span class="keyword">throw</span> <span class="keyword">new</span> <span class="title class_">RuntimeException</span>(e);</span><br><span class="line">            }</span><br><span class="line">            System.out.println(<span class="string">"子线程1执行完毕"</span>);</span><br><span class="line">            latch.countDown();<span class="comment">//子线程1执行完毕后调用countDown方法</span></span><br><span class="line">        }).start();</span><br><span class="line"></span><br><span class="line">        <span class="keyword">new</span> <span class="title class_">Thread</span>(()-&gt;{</span><br><span class="line">            System.out.println(<span class="string">"子线程2正在执行"</span>);</span><br><span class="line">            <span class="keyword">try</span> {</span><br><span class="line">                Thread.sleep(<span class="number">3000</span>);</span><br><span class="line">            } <span class="keyword">catch</span> (InterruptedException e) {</span><br><span class="line">                <span class="keyword">throw</span> <span class="keyword">new</span> <span class="title class_">RuntimeException</span>(e);</span><br><span class="line">            }</span><br><span class="line">            System.out.println(<span class="string">"子线程2执行完毕"</span>);</span><br><span class="line">            latch.countDown();<span class="comment">//子线程2执行完毕后调用countDown方法</span></span><br><span class="line">        }).start();</span><br><span class="line">        System.out.println(<span class="string">"等待两个子线程执行完毕..."</span>);</span><br><span class="line">        <span class="comment">//在CountDownLatch上等待子线程执行完毕</span></span><br><span class="line">        latch.await();</span><br><span class="line">        System.out.println(<span class="string">"两个子线程都已经执行完毕，继续执行主线程"</span>);</span><br><span class="line">    }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>上面代码先定义了一个计数器个数为2的CountDownLatch,然后定义了两个子线程并启动该子线程，子线程在执行完业务代码后执行latch.countDown()减少一个信号量，表示自己已经执行完毕。主线程调用<code>latch.await()</code>阻塞等待，在所有子线程都执行完毕并调用了countDown函数时，表示所有线程均执行完毕，这时程序会主动唤醒主线程并接着执行主线程的业务逻辑。</p>
<h4 id="cyclicbarrier循环栅栏">CyclicBarrier(循环栅栏)</h4>
<p>CyclicBarrier(循环栅栏)是一个同步工具，可以实现让一组线程等待至某状态之后再全部同时执行。再所有等待线程都被释放之后，CyclicBarrier可被重用。CyclicBarrier的运行状态叫做Barrier状态，在调用await方法后，线程就处于Barrier状态。</p>
<p>CyclicBarrier中await方法的两种实现：</p>
<ul>
<li><code>public int await()</code>:挂起当前线程，直到所有线程都为Barrier状态再同时执行后续的任务。</li>
<li><code>public int await(long timeout,TimeUnit unit)</code>:设置一个超时时间，在超时时间过后，如果还有线程未达到Barrier状态，则不再等待，让达到Barrier状态的线程继续之后后续的任务。</li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">CyclicBarrierTest</span> {</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="type">int</span> threadCount=<span class="number">10</span>;<span class="comment">//请求的数量</span></span><br><span class="line">    <span class="comment">//需要同步的线程数量</span></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> CyclicBarrier cyclicBarrier=<span class="keyword">new</span> <span class="title class_">CyclicBarrier</span>(<span class="number">5</span>);</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> <span class="keyword">throws</span> InterruptedException {</span><br><span class="line">        <span class="comment">//创建线程池</span></span><br><span class="line">        <span class="type">ExecutorService</span> <span class="variable">threadPool</span> <span class="operator">=</span> Executors.newFixedThreadPool(<span class="number">10</span>);</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; threadCount; i++) {</span><br><span class="line">            <span class="keyword">final</span> <span class="type">int</span> threadNum=i;</span><br><span class="line">            Thread.sleep(<span class="number">1000</span>);</span><br><span class="line">            threadPool.execute(()-&gt;{</span><br><span class="line">                System.out.println(<span class="string">"threadNum:"</span>+threadNum+<span class="string">" is ready"</span>);</span><br><span class="line">                <span class="keyword">try</span> {</span><br><span class="line">                    <span class="comment">//等待其他线程也成为Barrier状态,超时时间设置30秒</span></span><br><span class="line">                    cyclicBarrier.await(<span class="number">30</span>, TimeUnit.SECONDS);</span><br><span class="line">                } <span class="keyword">catch</span> (Exception e) {</span><br><span class="line">                    System.out.println(<span class="string">"CyclicBarrierException"</span>);</span><br><span class="line">                }</span><br><span class="line">                System.out.println(<span class="string">"threadNum:"</span>+threadNum+<span class="string">" is finished"</span>);</span><br><span class="line">            });</span><br><span class="line">        }</span><br><span class="line">    }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<figure>
<img data-src="https://codeleader.oss-cn-beijing.aliyuncs.com/site/image-20230811113606308.png" alt=""><figcaption>image-20230811113606308</figcaption>
</figure>
<h4 id="semaphore信号量">Semaphore(信号量)</h4>
<p><code>synchronized</code> 和 <code>ReentrantLock</code> 都是一次只允许一个线程访问某个资源，而<code>Semaphore</code>(信号量)可以用来控制同时访问特定资源的线程数量。</p>
<p>Semaphore指信号量，用于控制同时访问某些资源的线程个数，具体做法为通过调用<code>acquire()</code>获得一个许可，以便其他线程继续使用。</p>
<p>Semaphore常用于多个线程共享有限资源的情况下，比如办公室有5台打印机，但是有5个员工需要使用，一台打印机同时只能被一个员工使用，其他员工排队等候，且只有该打印机使用完毕被“释放”后其他员工方可使用。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">SemaphoreTest</span> {</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> {</span><br><span class="line">        <span class="type">int</span> printNumber=<span class="number">5</span>;<span class="comment">//设置线程数，即员工数量</span></span><br><span class="line">        <span class="type">Semaphore</span> <span class="variable">semaphore</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Semaphore</span>(<span class="number">2</span>);</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; printNumber; i++) {</span><br><span class="line">            <span class="keyword">new</span> <span class="title class_">Worker</span>(i,semaphore).start();</span><br><span class="line">        }</span><br><span class="line">    }</span><br><span class="line">    <span class="keyword">static</span> <span class="keyword">class</span> <span class="title class_">Worker</span> <span class="keyword">extends</span> <span class="title class_">Thread</span>{</span><br><span class="line">        <span class="keyword">private</span> <span class="type">int</span> num;</span><br><span class="line">        <span class="keyword">private</span> Semaphore semaphore;</span><br><span class="line">        <span class="keyword">public</span> <span class="title function_">Worker</span><span class="params">(<span class="type">int</span> num,Semaphore semaphore)</span>{</span><br><span class="line">            <span class="built_in">this</span>.num=num;</span><br><span class="line">            <span class="built_in">this</span>.semaphore=semaphore;</span><br><span class="line">        }</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">run</span><span class="params">()</span> {</span><br><span class="line">            <span class="keyword">try</span> {</span><br><span class="line">                semaphore.acquire();<span class="comment">//线程申请资源，即员工申请打印机</span></span><br><span class="line">                System.out.println(<span class="string">"员工:"</span>+<span class="built_in">this</span>.num+<span class="string">"占用一个打印机..."</span>);</span><br><span class="line">                Thread.sleep(<span class="number">2000</span>);</span><br><span class="line">                System.out.println(<span class="string">"员工："</span>+<span class="built_in">this</span>.num+<span class="string">"打印完成，释放打印机"</span>);</span><br><span class="line">                semaphore.release();    <span class="comment">//线程释放资源，即员工在使用完毕后”释放打印机“</span></span><br><span class="line">            } <span class="keyword">catch</span> (InterruptedException e) {</span><br><span class="line">                <span class="keyword">throw</span> <span class="keyword">new</span> <span class="title class_">RuntimeException</span>(e);</span><br><span class="line">            }</span><br><span class="line"></span><br><span class="line">        }</span><br><span class="line">    }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<figure>
<img data-src="https://codeleader.oss-cn-beijing.aliyuncs.com/site/image-20230811135708995.png" alt=""><figcaption>image-20230811135708995</figcaption>
</figure>
<h3 id="countdownlatch和cyclicbarrier的区别">CountDownLatch和CyclicBarrier的区别</h3>
<p>CountDownLatch和CyclicBarrier都用于实现多线程之间的相互等待，但二者的关注点不同。</p>
<p>CountDownLatch主要用于主线程等待其他子线程任务均执行完毕后再执行接下来的业务逻辑单元，而CyclicBarrier主要用于一组线程互相等待各线程都达到某个状态后，再同时执行接下来的业务逻辑单元。</p>
<p>CountDownLatch是不可以重用的，而CyclicBarrier是可以重用的。</p>
<blockquote>
<p>Semaphore和Java中的锁功能类似，主要用于控制资源的并发访问。</p>
</blockquote>
<h3 id="cas原理">CAS原理</h3>
<p>CAS(Compare And Swap,比较并交换)，用于实现乐观锁，基本思想是用一个期望值和要更新的变量值进行比较，两值相等才会更新。</p>
<blockquote>
<p>CAS是一个原子操作，底层依赖于一条CPU的原子指令。</p>
</blockquote>
<p>CAS(V,E,N)包含3个参数：</p>
<ul>
<li>V:要更新的变量</li>
<li>E:期望值</li>
<li>N:新值</li>
</ul>
<p>当且仅当<span class="math inline"><mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.186ex;" xmlns="http://www.w3.org/2000/svg" width="6.485ex" height="1.731ex" role="img" focusable="false" viewBox="0 -683 2866.6 765"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="mi"><path data-c="1D449" d="M52 648Q52 670 65 683H76Q118 680 181 680Q299 680 320 683H330Q336 677 336 674T334 656Q329 641 325 637H304Q282 635 274 635Q245 630 242 620Q242 618 271 369T301 118L374 235Q447 352 520 471T595 594Q599 601 599 609Q599 633 555 637Q537 637 537 648Q537 649 539 661Q542 675 545 679T558 683Q560 683 570 683T604 682T668 681Q737 681 755 683H762Q769 676 769 672Q769 655 760 640Q757 637 743 637Q730 636 719 635T698 630T682 623T670 615T660 608T652 599T645 592L452 282Q272 -9 266 -16Q263 -18 259 -21L241 -22H234Q216 -22 216 -15Q213 -9 177 305Q139 623 138 626Q133 637 76 637H59Q52 642 52 648Z"></path></g><g data-mml-node="mo" transform="translate(1046.8,0)"><path data-c="3D" d="M56 347Q56 360 70 367H707Q722 359 722 347Q722 336 708 328L390 327H72Q56 332 56 347ZM56 153Q56 168 72 173H708Q722 163 722 153Q722 140 707 133H70Q56 140 56 153Z"></path></g><g data-mml-node="mi" transform="translate(2102.6,0)"><path data-c="1D438" d="M492 213Q472 213 472 226Q472 230 477 250T482 285Q482 316 461 323T364 330H312Q311 328 277 192T243 52Q243 48 254 48T334 46Q428 46 458 48T518 61Q567 77 599 117T670 248Q680 270 683 272Q690 274 698 274Q718 274 718 261Q613 7 608 2Q605 0 322 0H133Q31 0 31 11Q31 13 34 25Q38 41 42 43T65 46Q92 46 125 49Q139 52 144 61Q146 66 215 342T285 622Q285 629 281 629Q273 632 228 634H197Q191 640 191 642T193 659Q197 676 203 680H757Q764 676 764 669Q764 664 751 557T737 447Q735 440 717 440H705Q698 445 698 453L701 476Q704 500 704 528Q704 558 697 578T678 609T643 625T596 632T532 634H485Q397 633 392 631Q388 629 386 622Q385 619 355 499T324 377Q347 376 372 376H398Q464 376 489 391T534 472Q538 488 540 490T557 493Q562 493 565 493T570 492T572 491T574 487T577 483L544 351Q511 218 508 216Q505 213 492 213Z"></path></g></g></g></svg></mjx-container></span>，才会将V的值设置为N,如果<span class="math inline"><mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.186ex;" xmlns="http://www.w3.org/2000/svg" width="7.114ex" height="1.805ex" role="img" focusable="false" viewBox="0 -716 3144.6 798"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="mi"><path data-c="1D449" d="M52 648Q52 670 65 683H76Q118 680 181 680Q299 680 320 683H330Q336 677 336 674T334 656Q329 641 325 637H304Q282 635 274 635Q245 630 242 620Q242 618 271 369T301 118L374 235Q447 352 520 471T595 594Q599 601 599 609Q599 633 555 637Q537 637 537 648Q537 649 539 661Q542 675 545 679T558 683Q560 683 570 683T604 682T668 681Q737 681 755 683H762Q769 676 769 672Q769 655 760 640Q757 637 743 637Q730 636 719 635T698 630T682 623T670 615T660 608T652 599T645 592L452 282Q272 -9 266 -16Q263 -18 259 -21L241 -22H234Q216 -22 216 -15Q213 -9 177 305Q139 623 138 626Q133 637 76 637H59Q52 642 52 648Z"></path></g><g data-mml-node="mo" transform="translate(769,0)"><path data-c="21" d="M78 661Q78 682 96 699T138 716T180 700T199 661Q199 654 179 432T158 206Q156 198 139 198Q121 198 119 206Q118 209 98 431T78 661ZM79 61Q79 89 97 105T141 121Q164 119 181 104T198 61Q198 31 181 16T139 1Q114 1 97 16T79 61Z"></path></g><g data-mml-node="mo" transform="translate(1324.8,0)"><path data-c="3D" d="M56 347Q56 360 70 367H707Q722 359 722 347Q722 336 708 328L390 327H72Q56 332 56 347ZM56 153Q56 168 72 173H708Q722 163 722 153Q722 140 707 133H70Q56 140 56 153Z"></path></g><g data-mml-node="mi" transform="translate(2380.6,0)"><path data-c="1D438" d="M492 213Q472 213 472 226Q472 230 477 250T482 285Q482 316 461 323T364 330H312Q311 328 277 192T243 52Q243 48 254 48T334 46Q428 46 458 48T518 61Q567 77 599 117T670 248Q680 270 683 272Q690 274 698 274Q718 274 718 261Q613 7 608 2Q605 0 322 0H133Q31 0 31 11Q31 13 34 25Q38 41 42 43T65 46Q92 46 125 49Q139 52 144 61Q146 66 215 342T285 622Q285 629 281 629Q273 632 228 634H197Q191 640 191 642T193 659Q197 676 203 680H757Q764 676 764 669Q764 664 751 557T737 447Q735 440 717 440H705Q698 445 698 453L701 476Q704 500 704 528Q704 558 697 578T678 609T643 625T596 632T532 634H485Q397 633 392 631Q388 629 386 622Q385 619 355 499T324 377Q347 376 372 376H398Q464 376 489 391T534 472Q538 488 540 490T557 493Q562 493 565 493T570 492T572 491T574 487T577 483L544 351Q511 218 508 216Q505 213 492 213Z"></path></g></g></g></svg></mjx-container></span>,说明已经有其他线程做了更新，当前线程什么都不做，最后CAS返回当前V的真实值。</p>
<p><strong>CAS的特性-乐观锁：</strong>CAS操作采用了乐观锁的思想，总是认为自己可以成功完成操作。在有多个线程同时使用CAS操作一个变量时，只有一个会胜出并成功更新，其余均会失败。失败的线程不会被挂起，仅被告知失败，并且允许再次尝试，当然，也允许失败的线程放弃操作。基于这样的原理，CAS操作即使没有锁，也可以发现其他线程对当前线程的干扰，并进行恰当的处理。</p>
<p>CAS导致的问题：ABA问题</p>
<h3 id="aba问题怎么解决">ABA问题？怎么解决？</h3>
<p>CAS算法需要取出内存种某时刻的数据，然后在下一时刻进行比较、替换，在这个时间差内可能数据已经发生了变化，导致产生ABA问题。</p>
<p>ABA问题指第1个线程从内存的V位置取出A，这时第2个线程也从内存中取出A,并将V位置的数据首先修改为B，接着又将V位置的数据修改为A,这时第1个线程在进行CAS操作时会发现在内存中仍然是A，然后第1个线程修改成功。尽管从第1个线程的角度来说，CAS操作是成功的，但在该过程中其实V位置的数据发生了变化，只是第1个线程没有感知到，这在某些场景下可能出现过程数据不一致的问题。</p>
<p>解决方案:<strong>版本号</strong></p>
<p><strong>通过版本号(version)来解决ABA问题</strong>，具体的操作是每次在执行数据修改的时都会带上一个版本号，在预期的版本号和数据的版本号一致时就可以执行修改操作，并对版本号执行加1操作，否则执行失败。因为每次操作的版本号都会随之增加，所以不会出现ABA问题，因为版本号只会增加，不会减少。</p>
<h3 id="aqs">AQS</h3>
<p>AQS(Abstract Queue Synchronizer)是一个抽象的队列同步器，通过维护一个共享资源状态(Volatile Int State)和一个先入先出(FIFO)的线程等待队列来实现一个多线程共享资源的同步框架。</p>
<blockquote>
<p>ReentrantLock，Semaphore，CountDownLatch等都是基于AQS的</p>
</blockquote>
<h4 id="aqs的原理"><strong>AQS的原理</strong></h4>
<p>AQS的核心思想是，如果被请求的共享资源空闲，则将当前请求资源的线程设置为有效的工作线程，并且将共享资源设置为锁定状态。如果被请求的共享资源被占用，那么就需要一套线程阻塞等待以及被唤醒时锁分配的机制，这个机制AQS是用<strong>CLH队列锁</strong>实现的，即将暂时获取不到锁的线程加入到队列中。</p>
<figure>
<img data-src="https://codeleader.oss-cn-beijing.aliyuncs.com/site/image-20230811100217214.png" alt=""><figcaption>image-20230811100217214</figcaption>
</figure>
<p>AQS维护了一个<code>volatile int</code>类型的变量，用于表示当前线程的同步状态。volatile虽然不能保证操作的原子性，但是能保证当前变量state的可见性。</p>
<p>state的访问方式有三种:<code>getState()</code>、<code>setState()</code>和<code>compareAndSetState()</code>，均是原子操作。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//返回同步状态的当前值</span></span><br><span class="line"><span class="keyword">protected</span> <span class="keyword">final</span> <span class="type">int</span> <span class="title function_">getState</span><span class="params">()</span> {</span><br><span class="line">     <span class="keyword">return</span> state;</span><br><span class="line">}</span><br><span class="line"> <span class="comment">//设置同步状态的值</span></span><br><span class="line"><span class="keyword">protected</span> <span class="keyword">final</span> <span class="keyword">void</span> <span class="title function_">setState</span><span class="params">(<span class="type">int</span> newState)</span> {</span><br><span class="line">     state = newState;</span><br><span class="line">}</span><br><span class="line"><span class="comment">//原子地（CAS操作）将同步状态值设置为给定值update 如果当前同步状态的值等于expect（期望值）</span></span><br><span class="line"><span class="keyword">protected</span> <span class="keyword">final</span> <span class="type">boolean</span> <span class="title function_">compareAndSetState</span><span class="params">(<span class="type">int</span> expect, <span class="type">int</span> update)</span> {</span><br><span class="line">      <span class="keyword">return</span> unsafe.compareAndSwapInt(<span class="built_in">this</span>, stateOffset, expect, update);</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h4 id="aqs共享资源的方式独占式和共享式">AQS共享资源的方式：独占式和共享式</h4>
<ul>
<li>独占式(Exclusive):只有一个线程能执行，具体的Java实现有<code>ReentrantLock</code>。</li>
<li>共享式(Share):多个线程可同时执行，具体的Java实现有<code>Semaphore</code>和<code>CountDownLatch</code>。</li>
</ul>
<p>自定义同步器的主要方法如下：</p>
<ul>
<li><code>isHeldExclusively()</code>:查询该线程是否正在独占资源，只有用到condition才需要去实现它。</li>
<li><code>tryAcquire(int)</code>:独占方式，尝试获取资源，成功返回true，失败返回false</li>
<li><code>tryRelease(int)</code>:独占方式，尝试释放资源，成功返回true，失败返回false</li>
<li><code>tryAcquireShared(int)</code>:共享方式，尝试获取资源：负数表示失败；0表示成功，但没有剩余可用资源；正数表示成功且有剩余可用资源。</li>
<li><code>tryReleaseShared(int)</code>:共享方式，尝试释放资源</li>
</ul>
<p><strong>ReentrantLock对AQS的独占方式实现</strong>：ReentrankLock中的state初始值为0时表示无锁状态，在线程执行<code>lock()</code>时，会调用<code>tryAcquire()</code>获取该锁将state+1,这时该线程独占ReentrantLock锁，其他线程在通过<code>tryAcquire()</code>获取锁时均会失败，直到该线程执行<code>unlock()</code>释放锁后state再次为0，其他线程才有机会获取该锁。该线程在释放锁之前可以重复获取该锁，每获取一次便会执行一次state+1，因此<strong>ReentrantLock也属于可重入锁</strong>。但获取多少次锁就要释放多少次锁，这样才能保证state最终为0。如果获取锁的次数多于释放锁的次数，则会出现该线程一直持有该锁的情况；如果获取锁的次数少于释放锁的次数，则运行中的程序会抛出锁异常。</p>
<p><strong>CountDownLatch对AQS的共享方式实现</strong>: CountDownLatch将任务分为N个子线程去执行，将state也初始化为N,N与线程的个数一致，N个子线程是并行执行的，每个子线程都在执行完后countDown()一次，state会执行CAS操作并减1。在所有子线程都执行完成(此时state=0)时会unpark()主线程，然后主线程会从await()返回，继续执行后续的动作。</p>
<h3 id="ioc的理解">IOC的理解</h3>
<p>IoC(Inversion of Controll,控制反转)是一种设计思想，而不是一个具体的技术实现。IoC的思想就是将原本在程序中手动创建对象的控制权交给Spring框架来管理。</p>
<p>将对象之间的相互依赖关系交给IoC容器来管理，并由IoC容器完成对象的注入。这样可以很大程度上简化应用的开发，把应用从复杂的依赖关系中解放出来。IoC容器就像是一个工厂一样，当我们需要创建一个对象的时候，只需要配置好配置文件/注解即可，完全不用考虑对象是如何被创建出来的。</p>
<p>优点：<strong>降低代码耦合度</strong>和<strong>集中资源统一管理，简化开发</strong>。</p>
<p><strong>Spring IOC的实现机制</strong>：简单来说就是解析xml文件获取到对象信息，通过反射获取字节码文件，然后通过字节码文件创建对象，并且在创建对象的过程中使用了工厂模式。</p>
<h3 id="项目主要负责哪些工作">项目主要负责哪些工作？</h3>
<h3 id="数据量大怎么办分库分表具体怎么设计">数据量大怎么办，分库分表具体怎么设计？</h3>
<h3 id="项目中多线程怎么用的">项目中多线程怎么用的？</h3>
<h3 id="熔断降级上下游怎么处理">熔断降级上下游怎么处理？</h3>
<h3 id="除了将日志保存到数据库还可以怎么处理">除了将日志保存到数据库还可以怎么处理？</h3>
<h3 id="编程力扣151反转字符串中的单词">编程：力扣151反转字符串中的单词</h3>

    </div>

    
    
    

    <footer class="post-footer">
          

<div class="post-copyright">
<ul>
  <li class="post-copyright-author">
      <strong>本文作者： </strong>别团等shy哥发育
  </li>
  <li class="post-copyright-link">
      <strong>本文链接：</strong>
      <a href="https://codeleader.gitee.io/hexo/2023/08/11/%E5%BF%AB%E6%89%8B%E4%B8%80%E9%9D%A2/" title="快手一面">https://codeleader.gitee.io/hexo/2023/08/11/快手一面/</a>
  </li>
  <li class="post-copyright-license">
    <strong>版权声明： </strong>本博客所有文章除特别声明外，均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" rel="noopener" target="_blank"><i class="fab fa-fw fa-creative-commons"></i>BY-NC-SA</a> 许可协议。转载请注明出处！
  </li>
</ul>
</div>

          <div class="post-tags">
              <a href="/hexo/tags/Java/" rel="tag"># Java</a>
              <a href="/hexo/tags/%E9%9D%A2%E7%BB%8F/" rel="tag"># 面经</a>
              <a href="/hexo/tags/MySQL/" rel="tag"># MySQL</a>
              <a href="/hexo/tags/Redis/" rel="tag"># Redis</a>
              <a href="/hexo/tags/RabbitMQ/" rel="tag"># RabbitMQ</a>
          </div>

        

          <div class="post-nav">
            <div class="post-nav-item">
                <a href="/hexo/2023/07/08/Java%E9%9B%86%E5%90%88%E5%A4%8D%E4%B9%A0/" rel="prev" title="Java集合复习">
                  <i class="fa fa-chevron-left"></i> Java集合复习
                </a>
            </div>
            <div class="post-nav-item">
                <a href="/hexo/2023/08/11/%E9%9D%A2%E8%AF%95%E6%A0%B8%E5%BF%83%E7%9F%A5%E8%AF%86%E7%82%B9%E6%80%BB%E7%BB%93/" rel="next" title="面试知识点总结(持续更新中)">
                  面试知识点总结(持续更新中) <i class="fa fa-chevron-right"></i>
                </a>
            </div>
          </div>
    </footer>
  </article>
</div>






</div>
  </main>

  <footer class="footer">
    <div class="footer-inner">


<div class="copyright">
  &copy; 2022 – 
  <span itemprop="copyrightYear">2024</span>
  <span class="with-love">
    <i class="fa fa-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">别团等shy哥发育</span>
</div>
<div class="wordcount">
  <span class="post-meta-item">
    <span class="post-meta-item-icon">
      <i class="fa fa-chart-line"></i>
    </span>
    <span title="站点总字数">81k</span>
  </span>
  <span class="post-meta-item">
    <span class="post-meta-item-icon">
      <i class="fa fa-coffee"></i>
    </span>
    <span title="站点阅读时长">4:56</span>
  </span>
</div>
<div class="busuanzi-count">
    <span class="post-meta-item" id="busuanzi_container_site_uv">
      <span class="post-meta-item-icon">
        <i class="fa fa-user"></i>
      </span>
      <span class="site-uv" title="总访客量">
        <span id="busuanzi_value_site_uv"></span>
      </span>
    </span>
    <span class="post-meta-item" id="busuanzi_container_site_pv">
      <span class="post-meta-item-icon">
        <i class="fa fa-eye"></i>
      </span>
      <span class="site-pv" title="总访问量">
        <span id="busuanzi_value_site_pv"></span>
      </span>
    </span>
</div>

<!-- <br /> -->
<!-- 网站运行时间的设置 -->
<span id="timeDate">载入天数...</span>
<!-- <span id="times">载入时分秒...</span> -->
<script>
    var now = new Date();
    function createtime() {
        var grt= new Date("11/17/2022 8:00:00");//此处修改你的建站时间或者网站上线时间
        now.setTime(now.getTime()+250);
        days = (now - grt ) / 1000 / 60 / 60 / 24; dnum = Math.floor(days);
        hours = (now - grt ) / 1000 / 60 / 60 - (24 * dnum); hnum = Math.floor(hours);
        if(String(hnum).length ==1 ){hnum = "0" + hnum;} minutes = (now - grt ) / 1000 /60 - (24 * 60 * dnum) - (60 * hnum);
        mnum = Math.floor(minutes); if(String(mnum).length ==1 ){mnum = "0" + mnum;}
        seconds = (now - grt ) / 1000 - (24 * 60 * 60 * dnum) - (60 * 60 * hnum) - (60 * mnum);
        snum = Math.round(seconds); 
        if(String(snum).length ==1 ){snum = "0" + snum;}
        // var times = document.getElementById("times").innerHTML = hnum + " 小时 " + mnum + " 分 " + snum + " 秒";
        document.getElementById("timeDate").innerHTML = "本站已安全运行 "+dnum+" 天 "+hnum + " 小时 " + mnum + " 分 " + snum + " 秒";
    }
setInterval("createtime()",250);
</script>

    </div>
  </footer>

  

<noscript>
  <div class="noscript-warning">Theme NexT works best with JavaScript enabled</div>
</noscript>


  
  <script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js" integrity="sha256-XL2inqUJaslATFnHdJOi9GfQ60on8Wx1C2H8DYiN1xY=" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/lozad.js/1.16.0/lozad.min.js" integrity="sha256-mOFREFhqmHeQbXpK2lp4nA3qooVgACfh88fpJftLBbc=" crossorigin="anonymous"></script>
<script src="/hexo/js/comments.js"></script><script src="/hexo/js/utils.js"></script><script src="/hexo/js/motion.js"></script><script src="/hexo/js/next-boot.js"></script>

  <script src="https://cdnjs.cloudflare.com/ajax/libs/hexo-generator-searchdb/1.4.1/search.js" integrity="sha256-1kfA5uHPf65M5cphT2dvymhkuyHPQp5A53EGZOnOLmc=" crossorigin="anonymous"></script>
<script src="/hexo/js/third-party/search/local-search.js"></script>




  <script src="/hexo/js/third-party/pace.js"></script>

  
  <script async src="https://busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>




  

  <script class="next-config" data-name="enableMath" type="application/json">true</script><script class="next-config" data-name="mathjax" type="application/json">{"enable":true,"tags":"none","js":{"url":"https://cdnjs.cloudflare.com/ajax/libs/mathjax/3.2.2/es5/tex-mml-chtml.js","integrity":"sha256-MASABpB4tYktI2Oitl4t+78w/lyA+D7b/s9GEP0JOGI="}}</script>
<script src="/hexo/js/third-party/math/mathjax.js"></script>



</body>
</html>
